blob: 1229f4057caed6f1657dae3f8f9bf7bf03ca9bd5 [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"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000024#include "webrtc/base/gunit.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000025#include "webrtc/base/ssladapter.h"
26#include "webrtc/base/sslstreamadapter.h"
27#include "webrtc/base/stringutils.h"
28#include "webrtc/base/thread.h"
deadbeef9a6f4d42017-05-15 19:43:33 -070029#include "webrtc/base/virtualsocketserver.h"
kjellandera96e2d72016-02-04 23:52:28 -080030#include "webrtc/media/base/fakevideocapturer.h"
zhihuang38ede132017-06-15 12:52:32 -070031#include "webrtc/media/engine/webrtcmediaengine.h"
deadbeef953c2ce2017-01-09 14:53:41 -080032#include "webrtc/media/sctp/sctptransportinternal.h"
Taylor Brandstettera1c30352016-05-13 08:15:11 -070033#include "webrtc/p2p/base/fakeportallocator.h"
ossu7bb87ee2017-01-23 04:56:25 -080034#include "webrtc/pc/audiotrack.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010035#include "webrtc/pc/mediasession.h"
ossu7bb87ee2017-01-23 04:56:25 -080036#include "webrtc/pc/mediastream.h"
37#include "webrtc/pc/peerconnection.h"
38#include "webrtc/pc/streamcollection.h"
39#include "webrtc/pc/test/fakertccertificategenerator.h"
40#include "webrtc/pc/test/fakevideotracksource.h"
41#include "webrtc/pc/test/mockpeerconnectionobservers.h"
42#include "webrtc/pc/test/testsdpstrings.h"
43#include "webrtc/pc/videocapturertracksource.h"
44#include "webrtc/pc/videotrack.h"
kwibergac9f8762016-09-30 22:29:43 -070045#include "webrtc/test/gmock.h"
46
47#ifdef WEBRTC_ANDROID
ossu7bb87ee2017-01-23 04:56:25 -080048#include "webrtc/pc/test/androidtestinitializer.h"
kwibergac9f8762016-09-30 22:29:43 -070049#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050
51static const char kStreamLabel1[] = "local_stream_1";
52static const char kStreamLabel2[] = "local_stream_2";
53static const char kStreamLabel3[] = "local_stream_3";
54static const int kDefaultStunPort = 3478;
55static const char kStunAddressOnly[] = "stun:address";
56static const char kStunInvalidPort[] = "stun:address:-1";
57static const char kStunAddressPortAndMore1[] = "stun:address:port:more";
58static const char kStunAddressPortAndMore2[] = "stun:address:port more";
59static const char kTurnIceServerUri[] = "turn:user@turn.example.org";
60static const char kTurnUsername[] = "user";
61static const char kTurnPassword[] = "password";
62static const char kTurnHostname[] = "turn.example.org";
Peter Boström0c4e06b2015-10-07 12:23:21 +020063static const uint32_t kTimeout = 10000U;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064
deadbeefab9b2d12015-10-14 11:33:11 -070065static const char kStreams[][8] = {"stream1", "stream2"};
66static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
67static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
68
deadbeef5e97fb52015-10-15 12:49:08 -070069static const char kRecvonly[] = "recvonly";
70static const char kSendrecv[] = "sendrecv";
71
deadbeefab9b2d12015-10-14 11:33:11 -070072// Reference SDP with a MediaStream with label "stream1" and audio track with
73// id "audio_1" and a video track with id "video_1;
74static const char kSdpStringWithStream1[] =
75 "v=0\r\n"
76 "o=- 0 0 IN IP4 127.0.0.1\r\n"
77 "s=-\r\n"
78 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080079 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070080 "a=ice-ufrag:e5785931\r\n"
81 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
82 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
83 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070084 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070085 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080086 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070087 "a=rtpmap:103 ISAC/16000\r\n"
88 "a=ssrc:1 cname:stream1\r\n"
89 "a=ssrc:1 mslabel:stream1\r\n"
90 "a=ssrc:1 label:audiotrack0\r\n"
91 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080092 "a=ice-ufrag:e5785931\r\n"
93 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
94 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
95 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070096 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070097 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080098 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070099 "a=rtpmap:120 VP8/90000\r\n"
100 "a=ssrc:2 cname:stream1\r\n"
101 "a=ssrc:2 mslabel:stream1\r\n"
102 "a=ssrc:2 label:videotrack0\r\n";
103
zhihuang81c3a032016-11-17 12:06:24 -0800104// Reference SDP with a MediaStream with label "stream1" and audio track with
105// id "audio_1";
106static const char kSdpStringWithStream1AudioTrackOnly[] =
107 "v=0\r\n"
108 "o=- 0 0 IN IP4 127.0.0.1\r\n"
109 "s=-\r\n"
110 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800111 "m=audio 1 RTP/AVPF 103\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800112 "a=ice-ufrag:e5785931\r\n"
113 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
114 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
115 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800116 "a=mid:audio\r\n"
117 "a=sendrecv\r\n"
118 "a=rtpmap:103 ISAC/16000\r\n"
119 "a=ssrc:1 cname:stream1\r\n"
120 "a=ssrc:1 mslabel:stream1\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800121 "a=ssrc:1 label:audiotrack0\r\n"
122 "a=rtcp-mux\r\n";
zhihuang81c3a032016-11-17 12:06:24 -0800123
deadbeefab9b2d12015-10-14 11:33:11 -0700124// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
125// MediaStreams have one audio track and one video track.
126// This uses MSID.
127static const char kSdpStringWithStream1And2[] =
128 "v=0\r\n"
129 "o=- 0 0 IN IP4 127.0.0.1\r\n"
130 "s=-\r\n"
131 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800132 "a=msid-semantic: WMS stream1 stream2\r\n"
133 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700134 "a=ice-ufrag:e5785931\r\n"
135 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
136 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
137 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700138 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700139 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800140 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700141 "a=rtpmap:103 ISAC/16000\r\n"
142 "a=ssrc:1 cname:stream1\r\n"
143 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
144 "a=ssrc:3 cname:stream2\r\n"
145 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
146 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800147 "a=ice-ufrag:e5785931\r\n"
148 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
149 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
150 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700151 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700152 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800153 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700154 "a=rtpmap:120 VP8/0\r\n"
155 "a=ssrc:2 cname:stream1\r\n"
156 "a=ssrc:2 msid:stream1 videotrack0\r\n"
157 "a=ssrc:4 cname:stream2\r\n"
158 "a=ssrc:4 msid:stream2 videotrack1\r\n";
159
160// Reference SDP without MediaStreams. Msid is not supported.
161static const char kSdpStringWithoutStreams[] =
162 "v=0\r\n"
163 "o=- 0 0 IN IP4 127.0.0.1\r\n"
164 "s=-\r\n"
165 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800166 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700167 "a=ice-ufrag:e5785931\r\n"
168 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
169 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
170 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700171 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700172 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800173 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700174 "a=rtpmap:103 ISAC/16000\r\n"
175 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800176 "a=ice-ufrag:e5785931\r\n"
177 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
178 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
179 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700180 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700181 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800182 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700183 "a=rtpmap:120 VP8/90000\r\n";
184
185// Reference SDP without MediaStreams. Msid is supported.
186static const char kSdpStringWithMsidWithoutStreams[] =
187 "v=0\r\n"
188 "o=- 0 0 IN IP4 127.0.0.1\r\n"
189 "s=-\r\n"
190 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800191 "a=msid-semantic: WMS\r\n"
192 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700193 "a=ice-ufrag:e5785931\r\n"
194 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
195 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
196 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700197 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700198 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800199 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700200 "a=rtpmap:103 ISAC/16000\r\n"
201 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800202 "a=ice-ufrag:e5785931\r\n"
203 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
204 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
205 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700206 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700207 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800208 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700209 "a=rtpmap:120 VP8/90000\r\n";
210
211// Reference SDP without MediaStreams and audio only.
212static const char kSdpStringWithoutStreamsAudioOnly[] =
213 "v=0\r\n"
214 "o=- 0 0 IN IP4 127.0.0.1\r\n"
215 "s=-\r\n"
216 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800217 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700218 "a=ice-ufrag:e5785931\r\n"
219 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
220 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
221 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700222 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700223 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800224 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700225 "a=rtpmap:103 ISAC/16000\r\n";
226
227// Reference SENDONLY SDP without MediaStreams. Msid is not supported.
228static const char kSdpStringSendOnlyWithoutStreams[] =
229 "v=0\r\n"
230 "o=- 0 0 IN IP4 127.0.0.1\r\n"
231 "s=-\r\n"
232 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800233 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700234 "a=ice-ufrag:e5785931\r\n"
235 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
236 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
237 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700238 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700239 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700240 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800241 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700242 "a=rtpmap:103 ISAC/16000\r\n"
243 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800244 "a=ice-ufrag:e5785931\r\n"
245 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
246 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
247 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700248 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700249 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700250 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800251 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700252 "a=rtpmap:120 VP8/90000\r\n";
253
254static const char kSdpStringInit[] =
255 "v=0\r\n"
256 "o=- 0 0 IN IP4 127.0.0.1\r\n"
257 "s=-\r\n"
258 "t=0 0\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700259 "a=msid-semantic: WMS\r\n";
260
261static const char kSdpStringAudio[] =
262 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800263 "a=ice-ufrag:e5785931\r\n"
264 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
265 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
266 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700267 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700268 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800269 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700270 "a=rtpmap:103 ISAC/16000\r\n";
271
272static const char kSdpStringVideo[] =
273 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800274 "a=ice-ufrag:e5785931\r\n"
275 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
276 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
277 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700278 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700279 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800280 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700281 "a=rtpmap:120 VP8/90000\r\n";
282
283static const char kSdpStringMs1Audio0[] =
284 "a=ssrc:1 cname:stream1\r\n"
285 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
286
287static const char kSdpStringMs1Video0[] =
288 "a=ssrc:2 cname:stream1\r\n"
289 "a=ssrc:2 msid:stream1 videotrack0\r\n";
290
291static const char kSdpStringMs1Audio1[] =
292 "a=ssrc:3 cname:stream1\r\n"
293 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
294
295static const char kSdpStringMs1Video1[] =
296 "a=ssrc:4 cname:stream1\r\n"
297 "a=ssrc:4 msid:stream1 videotrack1\r\n";
298
deadbeef8662f942017-01-20 21:20:51 -0800299static const char kDtlsSdesFallbackSdp[] =
300 "v=0\r\n"
301 "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n"
302 "s=-\r\n"
303 "c=IN IP4 0.0.0.0\r\n"
304 "t=0 0\r\n"
305 "a=group:BUNDLE audio\r\n"
306 "a=msid-semantic: WMS\r\n"
307 "m=audio 1 RTP/SAVPF 0\r\n"
308 "a=sendrecv\r\n"
309 "a=rtcp-mux\r\n"
310 "a=mid:audio\r\n"
311 "a=ssrc:1 cname:stream1\r\n"
312 "a=ssrc:1 mslabel:stream1\r\n"
313 "a=ssrc:1 label:audiotrack0\r\n"
314 "a=ice-ufrag:e5785931\r\n"
315 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
316 "a=rtpmap:0 pcmu/8000\r\n"
317 "a=fingerprint:sha-1 "
318 "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
319 "a=setup:actpass\r\n"
320 "a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
321 "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
322 "dummy_session_params\r\n";
323
perkjd61bf802016-03-24 03:16:19 -0700324using ::testing::Exactly;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700325using cricket::StreamParams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326using webrtc::AudioSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700327using webrtc::AudioTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328using webrtc::AudioTrackInterface;
329using webrtc::DataBuffer;
330using webrtc::DataChannelInterface;
331using webrtc::FakeConstraints;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332using webrtc::IceCandidateInterface;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700333using webrtc::JsepSessionDescription;
deadbeefc80741f2015-10-22 13:14:45 -0700334using webrtc::MediaConstraintsInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700335using webrtc::MediaStream;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336using webrtc::MediaStreamInterface;
337using webrtc::MediaStreamTrackInterface;
338using webrtc::MockCreateSessionDescriptionObserver;
339using webrtc::MockDataChannelObserver;
340using webrtc::MockSetSessionDescriptionObserver;
341using webrtc::MockStatsObserver;
perkjd61bf802016-03-24 03:16:19 -0700342using webrtc::NotifierInterface;
343using webrtc::ObserverInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344using webrtc::PeerConnectionInterface;
345using webrtc::PeerConnectionObserver;
deadbeef293e9262017-01-11 12:28:30 -0800346using webrtc::RTCError;
347using webrtc::RTCErrorType;
deadbeefab9b2d12015-10-14 11:33:11 -0700348using webrtc::RtpReceiverInterface;
349using webrtc::RtpSenderInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350using webrtc::SdpParseError;
351using webrtc::SessionDescriptionInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700352using webrtc::StreamCollection;
353using webrtc::StreamCollectionInterface;
perkja3ede6c2016-03-08 01:27:48 +0100354using webrtc::VideoTrackSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700355using webrtc::VideoTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356using webrtc::VideoTrackInterface;
357
deadbeefab9b2d12015-10-14 11:33:11 -0700358typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
359
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360namespace {
361
362// Gets the first ssrc of given content type from the ContentInfo.
363bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
364 if (!content_info || !ssrc) {
365 return false;
366 }
367 const cricket::MediaContentDescription* media_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000368 static_cast<const cricket::MediaContentDescription*>(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 content_info->description);
370 if (!media_desc || media_desc->streams().empty()) {
371 return false;
372 }
373 *ssrc = media_desc->streams().begin()->first_ssrc();
374 return true;
375}
376
deadbeefd1a38b52016-12-10 13:15:33 -0800377// Get the ufrags out of an SDP blob. Useful for testing ICE restart
378// behavior.
379std::vector<std::string> GetUfrags(
380 const webrtc::SessionDescriptionInterface* desc) {
381 std::vector<std::string> ufrags;
382 for (const cricket::TransportInfo& info :
383 desc->description()->transport_infos()) {
384 ufrags.push_back(info.description.ice_ufrag);
385 }
386 return ufrags;
387}
388
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389void SetSsrcToZero(std::string* sdp) {
390 const char kSdpSsrcAtribute[] = "a=ssrc:";
391 const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
392 size_t ssrc_pos = 0;
393 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
394 std::string::npos) {
395 size_t end_ssrc = sdp->find(" ", ssrc_pos);
396 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
397 ssrc_pos = end_ssrc;
398 }
399}
400
deadbeefab9b2d12015-10-14 11:33:11 -0700401// Check if |streams| contains the specified track.
402bool ContainsTrack(const std::vector<cricket::StreamParams>& streams,
403 const std::string& stream_label,
404 const std::string& track_id) {
405 for (const cricket::StreamParams& params : streams) {
406 if (params.sync_label == stream_label && params.id == track_id) {
407 return true;
408 }
409 }
410 return false;
411}
412
413// Check if |senders| contains the specified sender, by id.
414bool ContainsSender(
415 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
416 const std::string& id) {
417 for (const auto& sender : senders) {
418 if (sender->id() == id) {
419 return true;
420 }
421 }
422 return false;
423}
424
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700425// Check if |senders| contains the specified sender, by id and stream id.
426bool ContainsSender(
427 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
428 const std::string& id,
429 const std::string& stream_id) {
430 for (const auto& sender : senders) {
deadbeefa601f5c2016-06-06 14:27:39 -0700431 if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700432 return true;
433 }
434 }
435 return false;
436}
437
deadbeefab9b2d12015-10-14 11:33:11 -0700438// Create a collection of streams.
439// CreateStreamCollection(1) creates a collection that
440// correspond to kSdpStringWithStream1.
441// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
442rtc::scoped_refptr<StreamCollection> CreateStreamCollection(
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700443 int number_of_streams,
444 int tracks_per_stream) {
deadbeefab9b2d12015-10-14 11:33:11 -0700445 rtc::scoped_refptr<StreamCollection> local_collection(
446 StreamCollection::Create());
447
448 for (int i = 0; i < number_of_streams; ++i) {
449 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
450 webrtc::MediaStream::Create(kStreams[i]));
451
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700452 for (int j = 0; j < tracks_per_stream; ++j) {
453 // Add a local audio track.
454 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
455 webrtc::AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j],
456 nullptr));
457 stream->AddTrack(audio_track);
deadbeefab9b2d12015-10-14 11:33:11 -0700458
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700459 // Add a local video track.
460 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
461 webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
462 webrtc::FakeVideoTrackSource::Create()));
463 stream->AddTrack(video_track);
464 }
deadbeefab9b2d12015-10-14 11:33:11 -0700465
466 local_collection->AddStream(stream);
467 }
468 return local_collection;
469}
470
471// Check equality of StreamCollections.
472bool CompareStreamCollections(StreamCollectionInterface* s1,
473 StreamCollectionInterface* s2) {
474 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
475 return false;
476 }
477
478 for (size_t i = 0; i != s1->count(); ++i) {
479 if (s1->at(i)->label() != s2->at(i)->label()) {
480 return false;
481 }
482 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
483 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
484 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
485 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
486
487 if (audio_tracks1.size() != audio_tracks2.size()) {
488 return false;
489 }
490 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
491 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
492 return false;
493 }
494 }
495 if (video_tracks1.size() != video_tracks2.size()) {
496 return false;
497 }
498 for (size_t j = 0; j != video_tracks1.size(); ++j) {
499 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
500 return false;
501 }
502 }
503 }
504 return true;
505}
506
perkjd61bf802016-03-24 03:16:19 -0700507// Helper class to test Observer.
508class MockTrackObserver : public ObserverInterface {
509 public:
510 explicit MockTrackObserver(NotifierInterface* notifier)
511 : notifier_(notifier) {
512 notifier_->RegisterObserver(this);
513 }
514
515 ~MockTrackObserver() { Unregister(); }
516
517 void Unregister() {
518 if (notifier_) {
519 notifier_->UnregisterObserver(this);
520 notifier_ = nullptr;
521 }
522 }
523
524 MOCK_METHOD0(OnChanged, void());
525
526 private:
527 NotifierInterface* notifier_;
528};
529
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530class MockPeerConnectionObserver : public PeerConnectionObserver {
531 public:
deadbeefab9b2d12015-10-14 11:33:11 -0700532 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {}
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200533 virtual ~MockPeerConnectionObserver() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000534 }
535 void SetPeerConnectionInterface(PeerConnectionInterface* pc) {
536 pc_ = pc;
537 if (pc) {
538 state_ = pc_->signaling_state();
539 }
540 }
nisseef8b61e2016-04-29 06:09:15 -0700541 void OnSignalingChange(
542 PeerConnectionInterface::SignalingState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000543 EXPECT_EQ(pc_->signaling_state(), new_state);
544 state_ = new_state;
545 }
deadbeefab9b2d12015-10-14 11:33:11 -0700546
547 MediaStreamInterface* RemoteStream(const std::string& label) {
548 return remote_streams_->find(label);
549 }
550 StreamCollectionInterface* remote_streams() const { return remote_streams_; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700551 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000552 last_added_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700553 remote_streams_->AddStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700555 void OnRemoveStream(
556 rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000557 last_removed_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700558 remote_streams_->RemoveStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 }
perkjdfb769d2016-02-09 03:09:43 -0800560 void OnRenegotiationNeeded() override { renegotiation_needed_ = true; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700561 void OnDataChannel(
562 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000563 last_datachannel_ = data_channel;
564 }
565
perkjdfb769d2016-02-09 03:09:43 -0800566 void OnIceConnectionChange(
567 PeerConnectionInterface::IceConnectionState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 EXPECT_EQ(pc_->ice_connection_state(), new_state);
zhihuang81c3a032016-11-17 12:06:24 -0800569 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 }
perkjdfb769d2016-02-09 03:09:43 -0800571 void OnIceGatheringChange(
572 PeerConnectionInterface::IceGatheringState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573 EXPECT_EQ(pc_->ice_gathering_state(), new_state);
perkjdfb769d2016-02-09 03:09:43 -0800574 ice_complete_ = new_state == PeerConnectionInterface::kIceGatheringComplete;
zhihuang81c3a032016-11-17 12:06:24 -0800575 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000576 }
perkjdfb769d2016-02-09 03:09:43 -0800577 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew,
579 pc_->ice_gathering_state());
580
581 std::string sdp;
582 EXPECT_TRUE(candidate->ToString(&sdp));
583 EXPECT_LT(0u, sdp.size());
584 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(),
585 candidate->sdp_mline_index(), sdp, NULL));
586 EXPECT_TRUE(last_candidate_.get() != NULL);
zhihuang81c3a032016-11-17 12:06:24 -0800587 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700588 }
589
590 void OnIceCandidatesRemoved(
591 const std::vector<cricket::Candidate>& candidates) override {
zhihuang81c3a032016-11-17 12:06:24 -0800592 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700593 }
594
595 void OnIceConnectionReceivingChange(bool receiving) override {
zhihuang81c3a032016-11-17 12:06:24 -0800596 callback_triggered_ = true;
597 }
598
zhihuangc63b8942016-12-02 15:41:10 -0800599 void OnAddTrack(
600 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
601 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
602 streams) override {
zhihuang81c3a032016-11-17 12:06:24 -0800603 EXPECT_TRUE(receiver != nullptr);
604 num_added_tracks_++;
605 last_added_track_label_ = receiver->id();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000606 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000607
608 // Returns the label of the last added stream.
609 // Empty string if no stream have been added.
610 std::string GetLastAddedStreamLabel() {
611 if (last_added_stream_.get())
612 return last_added_stream_->label();
613 return "";
614 }
615 std::string GetLastRemovedStreamLabel() {
616 if (last_removed_stream_.get())
617 return last_removed_stream_->label();
618 return "";
619 }
620
zhihuang9763d562016-08-05 11:14:50 -0700621 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000622 PeerConnectionInterface::SignalingState state_;
kwibergd1fe2812016-04-27 06:47:29 -0700623 std::unique_ptr<IceCandidateInterface> last_candidate_;
zhihuang9763d562016-08-05 11:14:50 -0700624 rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
deadbeefab9b2d12015-10-14 11:33:11 -0700625 rtc::scoped_refptr<StreamCollection> remote_streams_;
626 bool renegotiation_needed_ = false;
627 bool ice_complete_ = false;
zhihuang81c3a032016-11-17 12:06:24 -0800628 bool callback_triggered_ = false;
629 int num_added_tracks_ = 0;
630 std::string last_added_track_label_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000631
632 private:
zhihuang9763d562016-08-05 11:14:50 -0700633 rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
634 rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635};
636
637} // namespace
deadbeefab9b2d12015-10-14 11:33:11 -0700638
nisse528b7932017-05-08 03:21:43 -0700639// The PeerConnectionMediaConfig tests below verify that configuration and
640// constraints are propagated into the PeerConnection's MediaConfig. These
641// settings are intended for MediaChannel constructors, but that is not
642// exercised by these unittest.
zhihuang29ff8442016-07-27 11:07:25 -0700643class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
644 public:
zhihuang38ede132017-06-15 12:52:32 -0700645 static rtc::scoped_refptr<PeerConnectionFactoryForTest>
646 CreatePeerConnectionFactoryForTest() {
647 auto audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
648 auto audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
649
650 auto media_engine = std::unique_ptr<cricket::MediaEngineInterface>(
651 cricket::WebRtcMediaEngineFactory::Create(
652 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr,
653 nullptr, nullptr));
654
655 std::unique_ptr<webrtc::CallFactoryInterface> call_factory =
656 webrtc::CreateCallFactory();
657
658 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory =
659 webrtc::CreateRtcEventLogFactory();
660
661 return new rtc::RefCountedObject<PeerConnectionFactoryForTest>(
662 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
663 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr, nullptr,
664 nullptr, std::move(media_engine), std::move(call_factory),
665 std::move(event_log_factory));
666 }
667
668 PeerConnectionFactoryForTest(
669 rtc::Thread* network_thread,
670 rtc::Thread* worker_thread,
671 rtc::Thread* signaling_thread,
672 webrtc::AudioDeviceModule* default_adm,
673 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
674 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
675 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
676 cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
677 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
678 std::unique_ptr<cricket::MediaEngineInterface> media_engine,
679 std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
680 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory)
681 : webrtc::PeerConnectionFactory(network_thread,
682 worker_thread,
683 signaling_thread,
684 default_adm,
685 audio_encoder_factory,
686 audio_decoder_factory,
687 video_encoder_factory,
688 video_decoder_factory,
689 audio_mixer,
690 std::move(media_engine),
691 std::move(call_factory),
692 std::move(event_log_factory)) {}
kwiberg1e4e8cb2017-01-31 01:48:08 -0800693
zhihuang29ff8442016-07-27 11:07:25 -0700694 cricket::TransportController* CreateTransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700695 cricket::PortAllocator* port_allocator,
696 bool redetermine_role_on_ice_restart) override {
zhihuang29ff8442016-07-27 11:07:25 -0700697 transport_controller = new cricket::TransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700698 rtc::Thread::Current(), rtc::Thread::Current(), port_allocator,
deadbeef7914b8c2017-04-21 03:23:33 -0700699 redetermine_role_on_ice_restart, rtc::CryptoOptions());
zhihuang29ff8442016-07-27 11:07:25 -0700700 return transport_controller;
701 }
702
703 cricket::TransportController* transport_controller;
zhihuang29ff8442016-07-27 11:07:25 -0700704};
705
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706class PeerConnectionInterfaceTest : public testing::Test {
707 protected:
deadbeef9a6f4d42017-05-15 19:43:33 -0700708 PeerConnectionInterfaceTest()
deadbeef98e186c2017-05-16 18:00:06 -0700709 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
phoglund37ebcf02016-01-08 05:04:57 -0800710#ifdef WEBRTC_ANDROID
711 webrtc::InitializeAndroidObjects();
712#endif
713 }
714
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 virtual void SetUp() {
716 pc_factory_ = webrtc::CreatePeerConnectionFactory(
danilchape9021a32016-05-17 01:52:02 -0700717 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
718 nullptr, nullptr, nullptr);
719 ASSERT_TRUE(pc_factory_);
zhihuang29ff8442016-07-27 11:07:25 -0700720 pc_factory_for_test_ =
zhihuang38ede132017-06-15 12:52:32 -0700721 PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
zhihuang29ff8442016-07-27 11:07:25 -0700722 pc_factory_for_test_->Initialize();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 }
724
725 void CreatePeerConnection() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700726 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(), nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 }
728
deadbeef293e9262017-01-11 12:28:30 -0800729 // DTLS does not work in a loopback call, so is disabled for most of the
730 // tests in this file.
731 void CreatePeerConnectionWithoutDtls() {
732 FakeConstraints no_dtls_constraints;
733 no_dtls_constraints.AddMandatory(
734 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
735
736 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
737 &no_dtls_constraints);
738 }
739
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700741 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
742 constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 }
744
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700745 void CreatePeerConnectionWithIceTransportsType(
746 PeerConnectionInterface::IceTransportsType type) {
747 PeerConnectionInterface::RTCConfiguration config;
748 config.type = type;
749 return CreatePeerConnection(config, nullptr);
750 }
751
752 void CreatePeerConnectionWithIceServer(const std::string& uri,
753 const std::string& password) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800754 PeerConnectionInterface::RTCConfiguration config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 PeerConnectionInterface::IceServer server;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700756 server.uri = uri;
757 server.password = password;
758 config.servers.push_back(server);
759 CreatePeerConnection(config, nullptr);
760 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700762 void CreatePeerConnection(PeerConnectionInterface::RTCConfiguration config,
763 webrtc::MediaConstraintsInterface* constraints) {
kwibergd1fe2812016-04-27 06:47:29 -0700764 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800765 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
766 port_allocator_ = port_allocator.get();
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000767
deadbeef1dcb1642017-03-29 21:08:16 -0700768 // Create certificate generator unless DTLS constraint is explicitly set to
769 // false.
Henrik Boströmd79599d2016-06-01 13:58:50 +0200770 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000771 bool dtls;
772 if (FindConstraint(constraints,
773 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
774 &dtls,
Henrik Boström5e56c592015-08-11 10:33:13 +0200775 nullptr) && dtls) {
deadbeef8662f942017-01-20 21:20:51 -0800776 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
777 cert_generator.reset(fake_certificate_generator_);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000778 }
Henrik Boströmd79599d2016-06-01 13:58:50 +0200779 pc_ = pc_factory_->CreatePeerConnection(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800780 config, constraints, std::move(port_allocator),
Henrik Boströmd79599d2016-06-01 13:58:50 +0200781 std::move(cert_generator), &observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 ASSERT_TRUE(pc_.get() != NULL);
783 observer_.SetPeerConnectionInterface(pc_.get());
784 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
785 }
786
deadbeef0a6c4ca2015-10-06 11:38:28 -0700787 void CreatePeerConnectionExpectFail(const std::string& uri) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800788 PeerConnectionInterface::RTCConfiguration config;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700789 PeerConnectionInterface::IceServer server;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700790 server.uri = uri;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800791 config.servers.push_back(server);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700792
zhihuang9763d562016-08-05 11:14:50 -0700793 rtc::scoped_refptr<PeerConnectionInterface> pc;
hbosd7973cc2016-05-27 06:08:53 -0700794 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr,
795 &observer_);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800796 EXPECT_EQ(nullptr, pc);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700797 }
798
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799 void CreatePeerConnectionWithDifferentConfigurations() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700800 CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800801 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
802 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
803 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804 EXPECT_EQ(kDefaultStunPort,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800805 port_allocator_->stun_servers().begin()->port());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806
deadbeef0a6c4ca2015-10-06 11:38:28 -0700807 CreatePeerConnectionExpectFail(kStunInvalidPort);
808 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
809 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700811 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800812 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
813 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814 EXPECT_EQ(kTurnUsername,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800815 port_allocator_->turn_servers()[0].credentials.username);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 EXPECT_EQ(kTurnPassword,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800817 port_allocator_->turn_servers()[0].credentials.password);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818 EXPECT_EQ(kTurnHostname,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800819 port_allocator_->turn_servers()[0].ports[0].address.hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 }
821
822 void ReleasePeerConnection() {
823 pc_ = NULL;
824 observer_.SetPeerConnectionInterface(NULL);
825 }
826
deadbeefab9b2d12015-10-14 11:33:11 -0700827 void AddVideoStream(const std::string& label) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700829 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700831 rtc::scoped_refptr<VideoTrackSourceInterface> video_source(
deadbeef112b2e92017-02-10 20:13:37 -0800832 pc_factory_->CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(
833 new cricket::FakeVideoCapturer()),
834 NULL));
zhihuang9763d562016-08-05 11:14:50 -0700835 rtc::scoped_refptr<VideoTrackInterface> video_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836 pc_factory_->CreateVideoTrack(label + "v0", video_source));
837 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000838 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
840 observer_.renegotiation_needed_ = false;
841 }
842
843 void AddVoiceStream(const std::string& label) {
844 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700845 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700847 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 pc_factory_->CreateAudioTrack(label + "a0", NULL));
849 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000850 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
852 observer_.renegotiation_needed_ = false;
853 }
854
855 void AddAudioVideoStream(const std::string& stream_label,
856 const std::string& audio_track_label,
857 const std::string& video_track_label) {
858 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700859 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860 pc_factory_->CreateLocalMediaStream(stream_label));
zhihuang9763d562016-08-05 11:14:50 -0700861 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862 pc_factory_->CreateAudioTrack(
863 audio_track_label, static_cast<AudioSourceInterface*>(NULL)));
864 stream->AddTrack(audio_track.get());
zhihuang9763d562016-08-05 11:14:50 -0700865 rtc::scoped_refptr<VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -0700866 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -0800867 video_track_label, pc_factory_->CreateVideoSource(
868 std::unique_ptr<cricket::VideoCapturer>(
869 new cricket::FakeVideoCapturer()))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000871 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
873 observer_.renegotiation_needed_ = false;
874 }
875
kwibergd1fe2812016-04-27 06:47:29 -0700876 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700877 bool offer,
878 MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000879 rtc::scoped_refptr<MockCreateSessionDescriptionObserver>
880 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881 MockCreateSessionDescriptionObserver>());
882 if (offer) {
deadbeefc80741f2015-10-22 13:14:45 -0700883 pc_->CreateOffer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884 } else {
deadbeefc80741f2015-10-22 13:14:45 -0700885 pc_->CreateAnswer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000886 }
887 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700888 *desc = observer->MoveDescription();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889 return observer->result();
890 }
891
kwibergd1fe2812016-04-27 06:47:29 -0700892 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700893 MediaConstraintsInterface* constraints) {
894 return DoCreateOfferAnswer(desc, true, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895 }
896
kwibergd1fe2812016-04-27 06:47:29 -0700897 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700898 MediaConstraintsInterface* constraints) {
899 return DoCreateOfferAnswer(desc, false, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900 }
901
902 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000903 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
904 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 MockSetSessionDescriptionObserver>());
906 if (local) {
907 pc_->SetLocalDescription(observer, desc);
908 } else {
909 pc_->SetRemoteDescription(observer, desc);
910 }
zhihuang29ff8442016-07-27 11:07:25 -0700911 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
912 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
913 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914 return observer->result();
915 }
916
917 bool DoSetLocalDescription(SessionDescriptionInterface* desc) {
918 return DoSetSessionDescription(desc, true);
919 }
920
921 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) {
922 return DoSetSessionDescription(desc, false);
923 }
924
925 // Calls PeerConnection::GetStats and check the return value.
926 // It does not verify the values in the StatReports since a RTCP packet might
927 // be required.
928 bool DoGetStats(MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000929 rtc::scoped_refptr<MockStatsObserver> observer(
930 new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000931 if (!pc_->GetStats(
932 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard))
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933 return false;
934 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
935 return observer->called();
936 }
937
938 void InitiateCall() {
deadbeef293e9262017-01-11 12:28:30 -0800939 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940 // Create a local stream with audio&video tracks.
941 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
942 CreateOfferReceiveAnswer();
943 }
944
945 // Verify that RTP Header extensions has been negotiated for audio and video.
946 void VerifyRemoteRtpHeaderExtensions() {
947 const cricket::MediaContentDescription* desc =
948 cricket::GetFirstAudioContentDescription(
949 pc_->remote_description()->description());
950 ASSERT_TRUE(desc != NULL);
951 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
952
953 desc = cricket::GetFirstVideoContentDescription(
954 pc_->remote_description()->description());
955 ASSERT_TRUE(desc != NULL);
956 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
957 }
958
959 void CreateOfferAsRemoteDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700960 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -0700961 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 std::string sdp;
963 EXPECT_TRUE(offer->ToString(&sdp));
964 SessionDescriptionInterface* remote_offer =
965 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
966 sdp, NULL);
967 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
968 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
969 }
970
deadbeefab9b2d12015-10-14 11:33:11 -0700971 void CreateAndSetRemoteOffer(const std::string& sdp) {
972 SessionDescriptionInterface* remote_offer =
973 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
974 sdp, nullptr);
975 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
976 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
977 }
978
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979 void CreateAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700980 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -0700981 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
983 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
984 // audio codec change, even if the parameter has nothing to do with
985 // receiving. Not all parameters are serialized to SDP.
986 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
987 // the SessionDescription, it is necessary to do that here to in order to
988 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
989 // https://code.google.com/p/webrtc/issues/detail?id=1356
990 std::string sdp;
991 EXPECT_TRUE(answer->ToString(&sdp));
992 SessionDescriptionInterface* new_answer =
993 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
994 sdp, NULL);
995 EXPECT_TRUE(DoSetLocalDescription(new_answer));
996 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
997 }
998
999 void CreatePrAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001000 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001001 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002
1003 std::string sdp;
1004 EXPECT_TRUE(answer->ToString(&sdp));
1005 SessionDescriptionInterface* pr_answer =
1006 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
1007 sdp, NULL);
1008 EXPECT_TRUE(DoSetLocalDescription(pr_answer));
1009 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
1010 }
1011
1012 void CreateOfferReceiveAnswer() {
1013 CreateOfferAsLocalDescription();
1014 std::string sdp;
1015 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1016 CreateAnswerAsRemoteDescription(sdp);
1017 }
1018
1019 void CreateOfferAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001020 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001021 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1023 // audio codec change, even if the parameter has nothing to do with
1024 // receiving. Not all parameters are serialized to SDP.
1025 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1026 // the SessionDescription, it is necessary to do that here to in order to
1027 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1028 // https://code.google.com/p/webrtc/issues/detail?id=1356
1029 std::string sdp;
1030 EXPECT_TRUE(offer->ToString(&sdp));
1031 SessionDescriptionInterface* new_offer =
1032 webrtc::CreateSessionDescription(
1033 SessionDescriptionInterface::kOffer,
1034 sdp, NULL);
1035
1036 EXPECT_TRUE(DoSetLocalDescription(new_offer));
1037 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
mallinath@webrtc.org68cbd012014-01-22 00:16:46 +00001038 // Wait for the ice_complete message, so that SDP will have candidates.
1039 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001040 }
1041
deadbeefab9b2d12015-10-14 11:33:11 -07001042 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
1044 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001045 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001046 EXPECT_TRUE(DoSetRemoteDescription(answer));
1047 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1048 }
1049
deadbeefab9b2d12015-10-14 11:33:11 -07001050 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001051 webrtc::JsepSessionDescription* pr_answer =
1052 new webrtc::JsepSessionDescription(
1053 SessionDescriptionInterface::kPrAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001054 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001055 EXPECT_TRUE(DoSetRemoteDescription(pr_answer));
1056 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
1057 webrtc::JsepSessionDescription* answer =
1058 new webrtc::JsepSessionDescription(
1059 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001060 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061 EXPECT_TRUE(DoSetRemoteDescription(answer));
1062 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1063 }
1064
1065 // Help function used for waiting until a the last signaled remote stream has
1066 // the same label as |stream_label|. In a few of the tests in this file we
1067 // answer with the same session description as we offer and thus we can
1068 // check if OnAddStream have been called with the same stream as we offer to
1069 // send.
1070 void WaitAndVerifyOnAddStream(const std::string& stream_label) {
1071 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout);
1072 }
1073
1074 // Creates an offer and applies it as a local session description.
1075 // Creates an answer with the same SDP an the offer but removes all lines
1076 // that start with a:ssrc"
1077 void CreateOfferReceiveAnswerWithoutSsrc() {
1078 CreateOfferAsLocalDescription();
1079 std::string sdp;
1080 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1081 SetSsrcToZero(&sdp);
1082 CreateAnswerAsRemoteDescription(sdp);
1083 }
1084
deadbeefab9b2d12015-10-14 11:33:11 -07001085 // This function creates a MediaStream with label kStreams[0] and
1086 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
1087 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
kwiberg2bbff992016-03-16 11:03:04 -07001088 // is returned and the MediaStream is stored in
deadbeefab9b2d12015-10-14 11:33:11 -07001089 // |reference_collection_|
kwibergd1fe2812016-04-27 06:47:29 -07001090 std::unique_ptr<SessionDescriptionInterface>
kwiberg2bbff992016-03-16 11:03:04 -07001091 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1092 size_t number_of_video_tracks) {
1093 EXPECT_LE(number_of_audio_tracks, 2u);
1094 EXPECT_LE(number_of_video_tracks, 2u);
deadbeefab9b2d12015-10-14 11:33:11 -07001095
1096 reference_collection_ = StreamCollection::Create();
1097 std::string sdp_ms1 = std::string(kSdpStringInit);
1098
1099 std::string mediastream_label = kStreams[0];
1100
1101 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
1102 webrtc::MediaStream::Create(mediastream_label));
1103 reference_collection_->AddStream(stream);
1104
1105 if (number_of_audio_tracks > 0) {
1106 sdp_ms1 += std::string(kSdpStringAudio);
1107 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1108 AddAudioTrack(kAudioTracks[0], stream);
1109 }
1110 if (number_of_audio_tracks > 1) {
1111 sdp_ms1 += kSdpStringMs1Audio1;
1112 AddAudioTrack(kAudioTracks[1], stream);
1113 }
1114
1115 if (number_of_video_tracks > 0) {
1116 sdp_ms1 += std::string(kSdpStringVideo);
1117 sdp_ms1 += std::string(kSdpStringMs1Video0);
1118 AddVideoTrack(kVideoTracks[0], stream);
1119 }
1120 if (number_of_video_tracks > 1) {
1121 sdp_ms1 += kSdpStringMs1Video1;
1122 AddVideoTrack(kVideoTracks[1], stream);
1123 }
1124
kwibergd1fe2812016-04-27 06:47:29 -07001125 return std::unique_ptr<SessionDescriptionInterface>(
kwiberg2bbff992016-03-16 11:03:04 -07001126 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1127 sdp_ms1, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001128 }
1129
1130 void AddAudioTrack(const std::string& track_id,
1131 MediaStreamInterface* stream) {
1132 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1133 webrtc::AudioTrack::Create(track_id, nullptr));
1134 ASSERT_TRUE(stream->AddTrack(audio_track));
1135 }
1136
1137 void AddVideoTrack(const std::string& track_id,
1138 MediaStreamInterface* stream) {
1139 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -07001140 webrtc::VideoTrack::Create(track_id,
1141 webrtc::FakeVideoTrackSource::Create()));
deadbeefab9b2d12015-10-14 11:33:11 -07001142 ASSERT_TRUE(stream->AddTrack(video_track));
1143 }
1144
kwibergfd8be342016-05-14 19:44:11 -07001145 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
deadbeef293e9262017-01-11 12:28:30 -08001146 CreatePeerConnectionWithoutDtls();
zhihuang8f65cdf2016-05-06 18:40:30 -07001147 AddVoiceStream(kStreamLabel1);
kwibergfd8be342016-05-14 19:44:11 -07001148 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001149 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1150 return offer;
1151 }
1152
kwibergfd8be342016-05-14 19:44:11 -07001153 std::unique_ptr<SessionDescriptionInterface>
zhihuang8f65cdf2016-05-06 18:40:30 -07001154 CreateAnswerWithOneAudioStream() {
kwibergfd8be342016-05-14 19:44:11 -07001155 std::unique_ptr<SessionDescriptionInterface> offer =
zhihuang8f65cdf2016-05-06 18:40:30 -07001156 CreateOfferWithOneAudioStream();
1157 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergfd8be342016-05-14 19:44:11 -07001158 std::unique_ptr<SessionDescriptionInterface> answer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001159 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1160 return answer;
1161 }
1162
1163 const std::string& GetFirstAudioStreamCname(
1164 const SessionDescriptionInterface* desc) {
1165 const cricket::ContentInfo* audio_content =
1166 cricket::GetFirstAudioContent(desc->description());
1167 const cricket::AudioContentDescription* audio_desc =
1168 static_cast<const cricket::AudioContentDescription*>(
1169 audio_content->description);
1170 return audio_desc->streams()[0].cname;
1171 }
1172
deadbeef9a6f4d42017-05-15 19:43:33 -07001173 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1174 rtc::AutoSocketServerThread main_;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08001175 cricket::FakePortAllocator* port_allocator_ = nullptr;
deadbeef8662f942017-01-20 21:20:51 -08001176 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
zhihuang9763d562016-08-05 11:14:50 -07001177 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1178 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_;
1179 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001180 MockPeerConnectionObserver observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001181 rtc::scoped_refptr<StreamCollection> reference_collection_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001182};
1183
zhihuang29ff8442016-07-27 11:07:25 -07001184// Test that no callbacks on the PeerConnectionObserver are called after the
1185// PeerConnection is closed.
1186TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) {
zhihuang9763d562016-08-05 11:14:50 -07001187 rtc::scoped_refptr<PeerConnectionInterface> pc(
zhihuang29ff8442016-07-27 11:07:25 -07001188 pc_factory_for_test_->CreatePeerConnection(
1189 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr,
1190 nullptr, &observer_));
1191 observer_.SetPeerConnectionInterface(pc.get());
1192 pc->Close();
1193
1194 // No callbacks is expected to be called.
zhihuang81c3a032016-11-17 12:06:24 -08001195 observer_.callback_triggered_ = false;
zhihuang29ff8442016-07-27 11:07:25 -07001196 std::vector<cricket::Candidate> candidates;
1197 pc_factory_for_test_->transport_controller->SignalGatheringState(
1198 cricket::IceGatheringState{});
1199 pc_factory_for_test_->transport_controller->SignalCandidatesGathered(
1200 "", candidates);
1201 pc_factory_for_test_->transport_controller->SignalConnectionState(
1202 cricket::IceConnectionState{});
1203 pc_factory_for_test_->transport_controller->SignalCandidatesRemoved(
1204 candidates);
1205 pc_factory_for_test_->transport_controller->SignalReceiving(false);
zhihuang81c3a032016-11-17 12:06:24 -08001206 EXPECT_FALSE(observer_.callback_triggered_);
zhihuang29ff8442016-07-27 11:07:25 -07001207}
1208
zhihuang8f65cdf2016-05-06 18:40:30 -07001209// Generate different CNAMEs when PeerConnections are created.
1210// The CNAMEs are expected to be generated randomly. It is possible
1211// that the test fails, though the possibility is very low.
1212TEST_F(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
kwibergfd8be342016-05-14 19:44:11 -07001213 std::unique_ptr<SessionDescriptionInterface> offer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001214 CreateOfferWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001215 std::unique_ptr<SessionDescriptionInterface> offer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001216 CreateOfferWithOneAudioStream();
1217 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1218 GetFirstAudioStreamCname(offer2.get()));
1219}
1220
1221TEST_F(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
kwibergfd8be342016-05-14 19:44:11 -07001222 std::unique_ptr<SessionDescriptionInterface> answer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001223 CreateAnswerWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001224 std::unique_ptr<SessionDescriptionInterface> answer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001225 CreateAnswerWithOneAudioStream();
1226 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1227 GetFirstAudioStreamCname(answer2.get()));
1228}
1229
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001230TEST_F(PeerConnectionInterfaceTest,
1231 CreatePeerConnectionWithDifferentConfigurations) {
1232 CreatePeerConnectionWithDifferentConfigurations();
1233}
1234
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001235TEST_F(PeerConnectionInterfaceTest,
1236 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1237 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1238 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1239 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1240 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1241 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1242 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1243 port_allocator_->candidate_filter());
1244 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1245 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1246}
1247
1248// Test that when a PeerConnection is created with a nonzero candidate pool
1249// size, the pooled PortAllocatorSession is created with all the attributes
1250// in the RTCConfiguration.
1251TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
1252 PeerConnectionInterface::RTCConfiguration config;
1253 PeerConnectionInterface::IceServer server;
1254 server.uri = kStunAddressOnly;
1255 config.servers.push_back(server);
1256 config.type = PeerConnectionInterface::kRelay;
1257 config.disable_ipv6 = true;
1258 config.tcp_candidate_policy =
1259 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
honghaiz60347052016-05-31 18:29:12 -07001260 config.candidate_network_policy =
1261 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001262 config.ice_candidate_pool_size = 1;
1263 CreatePeerConnection(config, nullptr);
1264
1265 const cricket::FakePortAllocatorSession* session =
1266 static_cast<const cricket::FakePortAllocatorSession*>(
1267 port_allocator_->GetPooledSession());
1268 ASSERT_NE(nullptr, session);
1269 EXPECT_EQ(1UL, session->stun_servers().size());
1270 EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
1271 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
honghaiz60347052016-05-31 18:29:12 -07001272 EXPECT_LT(0U,
1273 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001274}
1275
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001276// Test that the PeerConnection initializes the port allocator passed into it,
1277// and on the correct thread.
1278TEST_F(PeerConnectionInterfaceTest,
1279 CreatePeerConnectionInitializesPortAllocator) {
1280 rtc::Thread network_thread;
1281 network_thread.Start();
1282 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1283 webrtc::CreatePeerConnectionFactory(
1284 &network_thread, rtc::Thread::Current(), rtc::Thread::Current(),
1285 nullptr, nullptr, nullptr));
1286 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1287 new cricket::FakePortAllocator(&network_thread, nullptr));
1288 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1289 PeerConnectionInterface::RTCConfiguration config;
1290 rtc::scoped_refptr<PeerConnectionInterface> pc(
1291 pc_factory->CreatePeerConnection(
1292 config, nullptr, std::move(port_allocator), nullptr, &observer_));
1293 // FakePortAllocator RTC_CHECKs that it's initialized on the right thread,
1294 // so all we have to do here is check that it's initialized.
1295 EXPECT_TRUE(raw_port_allocator->initialized());
1296}
1297
deadbeef46c73892016-11-16 19:42:04 -08001298// Check that GetConfiguration returns the configuration the PeerConnection was
1299// constructed with, before SetConfiguration is called.
1300TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
1301 PeerConnectionInterface::RTCConfiguration config;
1302 config.type = PeerConnectionInterface::kRelay;
1303 CreatePeerConnection(config, nullptr);
1304
1305 PeerConnectionInterface::RTCConfiguration returned_config =
1306 pc_->GetConfiguration();
1307 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1308}
1309
1310// Check that GetConfiguration returns the last configuration passed into
1311// SetConfiguration.
1312TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
1313 CreatePeerConnection();
1314
1315 PeerConnectionInterface::RTCConfiguration config;
1316 config.type = PeerConnectionInterface::kRelay;
1317 EXPECT_TRUE(pc_->SetConfiguration(config));
1318
1319 PeerConnectionInterface::RTCConfiguration returned_config =
1320 pc_->GetConfiguration();
1321 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1322}
1323
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324TEST_F(PeerConnectionInterfaceTest, AddStreams) {
deadbeef293e9262017-01-11 12:28:30 -08001325 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001326 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327 AddVoiceStream(kStreamLabel2);
1328 ASSERT_EQ(2u, pc_->local_streams()->count());
1329
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001330 // Test we can add multiple local streams to one peerconnection.
zhihuang9763d562016-08-05 11:14:50 -07001331 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332 pc_factory_->CreateLocalMediaStream(kStreamLabel3));
zhihuang9763d562016-08-05 11:14:50 -07001333 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1334 pc_factory_->CreateAudioTrack(kStreamLabel3,
1335 static_cast<AudioSourceInterface*>(NULL)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00001337 EXPECT_TRUE(pc_->AddStream(stream));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001338 EXPECT_EQ(3u, pc_->local_streams()->count());
1339
1340 // Remove the third stream.
1341 pc_->RemoveStream(pc_->local_streams()->at(2));
1342 EXPECT_EQ(2u, pc_->local_streams()->count());
1343
1344 // Remove the second stream.
1345 pc_->RemoveStream(pc_->local_streams()->at(1));
1346 EXPECT_EQ(1u, pc_->local_streams()->count());
1347
1348 // Remove the first stream.
1349 pc_->RemoveStream(pc_->local_streams()->at(0));
1350 EXPECT_EQ(0u, pc_->local_streams()->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351}
1352
deadbeefab9b2d12015-10-14 11:33:11 -07001353// Test that the created offer includes streams we added.
1354TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) {
deadbeef293e9262017-01-11 12:28:30 -08001355 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001356 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track");
kwibergd1fe2812016-04-27 06:47:29 -07001357 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001358 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001359
1360 const cricket::ContentInfo* audio_content =
1361 cricket::GetFirstAudioContent(offer->description());
1362 const cricket::AudioContentDescription* audio_desc =
1363 static_cast<const cricket::AudioContentDescription*>(
1364 audio_content->description);
1365 EXPECT_TRUE(
1366 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1367
1368 const cricket::ContentInfo* video_content =
1369 cricket::GetFirstVideoContent(offer->description());
1370 const cricket::VideoContentDescription* video_desc =
1371 static_cast<const cricket::VideoContentDescription*>(
1372 video_content->description);
1373 EXPECT_TRUE(
1374 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1375
1376 // Add another stream and ensure the offer includes both the old and new
1377 // streams.
1378 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2");
kwiberg2bbff992016-03-16 11:03:04 -07001379 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001380
1381 audio_content = cricket::GetFirstAudioContent(offer->description());
1382 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1383 audio_content->description);
1384 EXPECT_TRUE(
1385 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1386 EXPECT_TRUE(
1387 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2"));
1388
1389 video_content = cricket::GetFirstVideoContent(offer->description());
1390 video_desc = static_cast<const cricket::VideoContentDescription*>(
1391 video_content->description);
1392 EXPECT_TRUE(
1393 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1394 EXPECT_TRUE(
1395 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2"));
1396}
1397
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398TEST_F(PeerConnectionInterfaceTest, RemoveStream) {
deadbeef293e9262017-01-11 12:28:30 -08001399 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001400 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401 ASSERT_EQ(1u, pc_->local_streams()->count());
1402 pc_->RemoveStream(pc_->local_streams()->at(0));
1403 EXPECT_EQ(0u, pc_->local_streams()->count());
1404}
1405
deadbeefe1f9d832016-01-14 15:35:42 -08001406// Test for AddTrack and RemoveTrack methods.
1407// Tests that the created offer includes tracks we added,
1408// and that the RtpSenders are created correctly.
1409// Also tests that RemoveTrack removes the tracks from subsequent offers.
1410TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) {
deadbeef293e9262017-01-11 12:28:30 -08001411 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001412 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001413 rtc::scoped_refptr<MediaStreamInterface> stream(
deadbeefe1f9d832016-01-14 15:35:42 -08001414 pc_factory_->CreateLocalMediaStream(kStreamLabel1));
1415 std::vector<MediaStreamInterface*> stream_list;
1416 stream_list.push_back(stream.get());
zhihuang9763d562016-08-05 11:14:50 -07001417 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001418 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001419 rtc::scoped_refptr<VideoTrackInterface> video_track(
1420 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001421 "video_track", pc_factory_->CreateVideoSource(
1422 std::unique_ptr<cricket::VideoCapturer>(
1423 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001424 auto audio_sender = pc_->AddTrack(audio_track, stream_list);
1425 auto video_sender = pc_->AddTrack(video_track, stream_list);
deadbeefa601f5c2016-06-06 14:27:39 -07001426 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1427 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001428 EXPECT_EQ("audio_track", audio_sender->id());
1429 EXPECT_EQ(audio_track, audio_sender->track());
deadbeefa601f5c2016-06-06 14:27:39 -07001430 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1431 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001432 EXPECT_EQ("video_track", video_sender->id());
1433 EXPECT_EQ(video_track, video_sender->track());
1434
1435 // Now create an offer and check for the senders.
kwibergd1fe2812016-04-27 06:47:29 -07001436 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001437 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001438
1439 const cricket::ContentInfo* audio_content =
1440 cricket::GetFirstAudioContent(offer->description());
1441 const cricket::AudioContentDescription* audio_desc =
1442 static_cast<const cricket::AudioContentDescription*>(
1443 audio_content->description);
1444 EXPECT_TRUE(
1445 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1446
1447 const cricket::ContentInfo* video_content =
1448 cricket::GetFirstVideoContent(offer->description());
1449 const cricket::VideoContentDescription* video_desc =
1450 static_cast<const cricket::VideoContentDescription*>(
1451 video_content->description);
1452 EXPECT_TRUE(
1453 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1454
1455 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1456
1457 // Now try removing the tracks.
1458 EXPECT_TRUE(pc_->RemoveTrack(audio_sender));
1459 EXPECT_TRUE(pc_->RemoveTrack(video_sender));
1460
1461 // Create a new offer and ensure it doesn't contain the removed senders.
kwiberg2bbff992016-03-16 11:03:04 -07001462 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001463
1464 audio_content = cricket::GetFirstAudioContent(offer->description());
1465 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1466 audio_content->description);
1467 EXPECT_FALSE(
1468 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1469
1470 video_content = cricket::GetFirstVideoContent(offer->description());
1471 video_desc = static_cast<const cricket::VideoContentDescription*>(
1472 video_content->description);
1473 EXPECT_FALSE(
1474 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1475
1476 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1477
1478 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1479 // should return false.
1480 EXPECT_FALSE(pc_->RemoveTrack(audio_sender));
1481 EXPECT_FALSE(pc_->RemoveTrack(video_sender));
1482}
1483
1484// Test creating senders without a stream specified,
1485// expecting a random stream ID to be generated.
1486TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
deadbeef293e9262017-01-11 12:28:30 -08001487 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001488 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001489 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001490 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001491 rtc::scoped_refptr<VideoTrackInterface> video_track(
1492 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001493 "video_track", pc_factory_->CreateVideoSource(
1494 std::unique_ptr<cricket::VideoCapturer>(
1495 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001496 auto audio_sender =
1497 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>());
1498 auto video_sender =
1499 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>());
1500 EXPECT_EQ("audio_track", audio_sender->id());
1501 EXPECT_EQ(audio_track, audio_sender->track());
1502 EXPECT_EQ("video_track", video_sender->id());
1503 EXPECT_EQ(video_track, video_sender->track());
1504 // If the ID is truly a random GUID, it should be infinitely unlikely they
1505 // will be the same.
deadbeefa601f5c2016-06-06 14:27:39 -07001506 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
deadbeefe1f9d832016-01-14 15:35:42 -08001507}
1508
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
1510 InitiateCall();
1511 WaitAndVerifyOnAddStream(kStreamLabel1);
1512 VerifyRemoteRtpHeaderExtensions();
1513}
1514
1515TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001516 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001517 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001518 CreateOfferAsLocalDescription();
1519 std::string offer;
1520 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1521 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
1522 WaitAndVerifyOnAddStream(kStreamLabel1);
1523}
1524
1525TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001526 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001527 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528
1529 CreateOfferAsRemoteDescription();
1530 CreateAnswerAsLocalDescription();
1531
1532 WaitAndVerifyOnAddStream(kStreamLabel1);
1533}
1534
1535TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001536 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001537 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538
1539 CreateOfferAsRemoteDescription();
1540 CreatePrAnswerAsLocalDescription();
1541 CreateAnswerAsLocalDescription();
1542
1543 WaitAndVerifyOnAddStream(kStreamLabel1);
1544}
1545
1546TEST_F(PeerConnectionInterfaceTest, Renegotiate) {
1547 InitiateCall();
1548 ASSERT_EQ(1u, pc_->remote_streams()->count());
1549 pc_->RemoveStream(pc_->local_streams()->at(0));
1550 CreateOfferReceiveAnswer();
1551 EXPECT_EQ(0u, pc_->remote_streams()->count());
deadbeefab9b2d12015-10-14 11:33:11 -07001552 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553 CreateOfferReceiveAnswer();
1554}
1555
1556// Tests that after negotiating an audio only call, the respondent can perform a
1557// renegotiation that removes the audio stream.
1558TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) {
deadbeef293e9262017-01-11 12:28:30 -08001559 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560 AddVoiceStream(kStreamLabel1);
1561 CreateOfferAsRemoteDescription();
1562 CreateAnswerAsLocalDescription();
1563
1564 ASSERT_EQ(1u, pc_->remote_streams()->count());
1565 pc_->RemoveStream(pc_->local_streams()->at(0));
1566 CreateOfferReceiveAnswer();
1567 EXPECT_EQ(0u, pc_->remote_streams()->count());
1568}
1569
1570// Test that candidates are generated and that we can parse our own candidates.
1571TEST_F(PeerConnectionInterfaceTest, IceCandidates) {
deadbeef293e9262017-01-11 12:28:30 -08001572 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573
1574 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1575 // SetRemoteDescription takes ownership of offer.
kwibergd1fe2812016-04-27 06:47:29 -07001576 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefab9b2d12015-10-14 11:33:11 -07001577 AddVideoStream(kStreamLabel1);
deadbeefc80741f2015-10-22 13:14:45 -07001578 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001579 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001580
1581 // SetLocalDescription takes ownership of answer.
kwibergd1fe2812016-04-27 06:47:29 -07001582 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001583 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001584 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585
1586 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout);
1587 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
1588
1589 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1590}
1591
deadbeefab9b2d12015-10-14 11:33:11 -07001592// Test that CreateOffer and CreateAnswer will fail if the track labels are
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593// not unique.
1594TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) {
deadbeef293e9262017-01-11 12:28:30 -08001595 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596 // Create a regular offer for the CreateAnswer test later.
kwibergd1fe2812016-04-27 06:47:29 -07001597 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07001598 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001599 EXPECT_TRUE(offer);
1600 offer.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601
1602 // Create a local stream with audio&video tracks having same label.
1603 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label");
1604
1605 // Test CreateOffer
deadbeefc80741f2015-10-22 13:14:45 -07001606 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
1608 // Test CreateAnswer
kwibergd1fe2812016-04-27 06:47:29 -07001609 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001610 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
1613// Test that we will get different SSRCs for each tracks in the offer and answer
1614// we created.
1615TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001616 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617 // Create a local stream with audio&video tracks having different labels.
1618 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1619
1620 // Test CreateOffer
kwibergd1fe2812016-04-27 06:47:29 -07001621 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001622 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623 int audio_ssrc = 0;
1624 int video_ssrc = 0;
1625 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()),
1626 &audio_ssrc));
1627 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()),
1628 &video_ssrc));
1629 EXPECT_NE(audio_ssrc, video_ssrc);
1630
1631 // Test CreateAnswer
1632 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergd1fe2812016-04-27 06:47:29 -07001633 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001634 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001635 audio_ssrc = 0;
1636 video_ssrc = 0;
1637 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()),
1638 &audio_ssrc));
1639 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()),
1640 &video_ssrc));
1641 EXPECT_NE(audio_ssrc, video_ssrc);
1642}
1643
deadbeefeb459812015-12-15 19:24:43 -08001644// Test that it's possible to call AddTrack on a MediaStream after adding
1645// the stream to a PeerConnection.
1646// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1647TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001648 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001649 // Create audio stream and add to PeerConnection.
1650 AddVoiceStream(kStreamLabel1);
1651 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1652
1653 // Add video track to the audio-only stream.
zhihuang9763d562016-08-05 11:14:50 -07001654 rtc::scoped_refptr<VideoTrackInterface> video_track(
1655 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001656 "video_label", pc_factory_->CreateVideoSource(
1657 std::unique_ptr<cricket::VideoCapturer>(
1658 new cricket::FakeVideoCapturer()))));
deadbeefeb459812015-12-15 19:24:43 -08001659 stream->AddTrack(video_track.get());
1660
kwibergd1fe2812016-04-27 06:47:29 -07001661 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001662 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001663
1664 const cricket::MediaContentDescription* video_desc =
1665 cricket::GetFirstVideoContentDescription(offer->description());
1666 EXPECT_TRUE(video_desc != nullptr);
1667}
1668
1669// Test that it's possible to call RemoveTrack on a MediaStream after adding
1670// the stream to a PeerConnection.
1671// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1672TEST_F(PeerConnectionInterfaceTest, RemoveTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001673 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001674 // Create audio/video stream and add to PeerConnection.
1675 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1676 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1677
1678 // Remove the video track.
1679 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1680
kwibergd1fe2812016-04-27 06:47:29 -07001681 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001682 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001683
1684 const cricket::MediaContentDescription* video_desc =
1685 cricket::GetFirstVideoContentDescription(offer->description());
1686 EXPECT_TRUE(video_desc == nullptr);
1687}
1688
deadbeef1dcb1642017-03-29 21:08:16 -07001689// Verify that CreateDtmfSender only succeeds if called with a valid local
1690// track. Other aspects of DtmfSenders are tested in
1691// peerconnection_integrationtest.cc.
1692TEST_F(PeerConnectionInterfaceTest, CreateDtmfSenderWithInvalidParams) {
1693 CreatePeerConnection();
1694 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1695 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(nullptr));
1696 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack(
1697 pc_factory_->CreateAudioTrack("dummy_track", nullptr));
1698 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(non_localtrack));
1699}
1700
deadbeefbd7d8f72015-12-18 16:58:44 -08001701// Test creating a sender with a stream ID, and ensure the ID is populated
1702// in the offer.
1703TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) {
deadbeef293e9262017-01-11 12:28:30 -08001704 CreatePeerConnectionWithoutDtls();
deadbeefbd7d8f72015-12-18 16:58:44 -08001705 pc_->CreateSender("video", kStreamLabel1);
1706
kwibergd1fe2812016-04-27 06:47:29 -07001707 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001708 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefbd7d8f72015-12-18 16:58:44 -08001709
1710 const cricket::MediaContentDescription* video_desc =
1711 cricket::GetFirstVideoContentDescription(offer->description());
1712 ASSERT_TRUE(video_desc != nullptr);
1713 ASSERT_EQ(1u, video_desc->streams().size());
1714 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label);
1715}
1716
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717// Test that we can specify a certain track that we want statistics about.
1718TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
1719 InitiateCall();
1720 ASSERT_LT(0u, pc_->remote_streams()->count());
1721 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001722 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001723 pc_->remote_streams()->at(0)->GetAudioTracks()[0];
1724 EXPECT_TRUE(DoGetStats(remote_audio));
1725
1726 // Remove the stream. Since we are sending to our selves the local
1727 // and the remote stream is the same.
1728 pc_->RemoveStream(pc_->local_streams()->at(0));
1729 // Do a re-negotiation.
1730 CreateOfferReceiveAnswer();
1731
1732 ASSERT_EQ(0u, pc_->remote_streams()->count());
1733
1734 // Test that we still can get statistics for the old track. Even if it is not
1735 // sent any longer.
1736 EXPECT_TRUE(DoGetStats(remote_audio));
1737}
1738
1739// Test that we can get stats on a video track.
1740TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
1741 InitiateCall();
1742 ASSERT_LT(0u, pc_->remote_streams()->count());
1743 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001744 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745 pc_->remote_streams()->at(0)->GetVideoTracks()[0];
1746 EXPECT_TRUE(DoGetStats(remote_video));
1747}
1748
1749// Test that we don't get statistics for an invalid track.
zhihuange9e94c32016-11-04 11:38:15 -07001750TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001751 InitiateCall();
zhihuang9763d562016-08-05 11:14:50 -07001752 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001753 pc_factory_->CreateAudioTrack("unknown track", NULL));
1754 EXPECT_FALSE(DoGetStats(unknown_audio_track));
1755}
1756
1757// This test setup two RTP data channels in loop back.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758TEST_F(PeerConnectionInterfaceTest, TestDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001759 FakeConstraints constraints;
1760 constraints.SetAllowRtpDataChannels();
1761 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001762 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001764 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765 pc_->CreateDataChannel("test2", NULL);
1766 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001767 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001769 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770 new MockDataChannelObserver(data2));
1771
1772 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1773 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1774 std::string data_to_send1 = "testing testing";
1775 std::string data_to_send2 = "testing something else";
1776 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1)));
1777
1778 CreateOfferReceiveAnswer();
1779 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1780 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1781
1782 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1783 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1784 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1)));
1785 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1786
1787 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout);
1788 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1789
1790 data1->Close();
1791 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1792 CreateOfferReceiveAnswer();
1793 EXPECT_FALSE(observer1->IsOpen());
1794 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1795 EXPECT_TRUE(observer2->IsOpen());
1796
1797 data_to_send2 = "testing something else again";
1798 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1799
1800 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1801}
1802
1803// This test verifies that sendnig binary data over RTP data channels should
1804// fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806 FakeConstraints constraints;
1807 constraints.SetAllowRtpDataChannels();
1808 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001809 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001811 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001812 pc_->CreateDataChannel("test2", NULL);
1813 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001814 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001816 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817 new MockDataChannelObserver(data2));
1818
1819 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1820 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1821
1822 CreateOfferReceiveAnswer();
1823 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1824 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1825
1826 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1827 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1828
jbaucheec21bd2016-03-20 06:15:43 -07001829 rtc::CopyOnWriteBuffer buffer("test", 4);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001830 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true)));
1831}
1832
1833// This test setup a RTP data channels in loop back and test that a channel is
1834// opened even if the remote end answer with a zero SSRC.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001836 FakeConstraints constraints;
1837 constraints.SetAllowRtpDataChannels();
1838 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001839 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840 pc_->CreateDataChannel("test1", NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001841 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842 new MockDataChannelObserver(data1));
1843
1844 CreateOfferReceiveAnswerWithoutSsrc();
1845
1846 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1847
1848 data1->Close();
1849 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1850 CreateOfferReceiveAnswerWithoutSsrc();
1851 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1852 EXPECT_FALSE(observer1->IsOpen());
1853}
1854
1855// This test that if a data channel is added in an answer a receive only channel
1856// channel is created.
1857TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) {
1858 FakeConstraints constraints;
1859 constraints.SetAllowRtpDataChannels();
1860 CreatePeerConnection(&constraints);
1861
1862 std::string offer_label = "offer_channel";
zhihuang9763d562016-08-05 11:14:50 -07001863 rtc::scoped_refptr<DataChannelInterface> offer_channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864 pc_->CreateDataChannel(offer_label, NULL);
1865
1866 CreateOfferAsLocalDescription();
1867
1868 // Replace the data channel label in the offer and apply it as an answer.
1869 std::string receive_label = "answer_channel";
1870 std::string sdp;
1871 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001872 rtc::replace_substrs(offer_label.c_str(), offer_label.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001873 receive_label.c_str(), receive_label.length(),
1874 &sdp);
1875 CreateAnswerAsRemoteDescription(sdp);
1876
1877 // Verify that a new incoming data channel has been created and that
1878 // it is open but can't we written to.
1879 ASSERT_TRUE(observer_.last_datachannel_ != NULL);
1880 DataChannelInterface* received_channel = observer_.last_datachannel_;
1881 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state());
1882 EXPECT_EQ(receive_label, received_channel->label());
1883 EXPECT_FALSE(received_channel->Send(DataBuffer("something")));
1884
1885 // Verify that the channel we initially offered has been rejected.
1886 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
1887
1888 // Do another offer / answer exchange and verify that the data channel is
1889 // opened.
1890 CreateOfferReceiveAnswer();
1891 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(),
1892 kTimeout);
1893}
1894
1895// This test that no data channel is returned if a reliable channel is
1896// requested.
1897// TODO(perkj): Remove this test once reliable channels are implemented.
1898TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) {
1899 FakeConstraints constraints;
1900 constraints.SetAllowRtpDataChannels();
1901 CreatePeerConnection(&constraints);
1902
1903 std::string label = "test";
1904 webrtc::DataChannelInit config;
1905 config.reliable = true;
zhihuang9763d562016-08-05 11:14:50 -07001906 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907 pc_->CreateDataChannel(label, &config);
1908 EXPECT_TRUE(channel == NULL);
1909}
1910
deadbeefab9b2d12015-10-14 11:33:11 -07001911// Verifies that duplicated label is not allowed for RTP data channel.
1912TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) {
1913 FakeConstraints constraints;
1914 constraints.SetAllowRtpDataChannels();
1915 CreatePeerConnection(&constraints);
1916
1917 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07001918 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001919 pc_->CreateDataChannel(label, nullptr);
1920 EXPECT_NE(channel, nullptr);
1921
zhihuang9763d562016-08-05 11:14:50 -07001922 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001923 pc_->CreateDataChannel(label, nullptr);
1924 EXPECT_EQ(dup_channel, nullptr);
1925}
1926
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001927// This tests that a SCTP data channel is returned using different
1928// DataChannelInit configurations.
1929TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
1930 FakeConstraints constraints;
1931 constraints.SetAllowDtlsSctpDataChannels();
1932 CreatePeerConnection(&constraints);
1933
1934 webrtc::DataChannelInit config;
1935
zhihuang9763d562016-08-05 11:14:50 -07001936 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937 pc_->CreateDataChannel("1", &config);
1938 EXPECT_TRUE(channel != NULL);
1939 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001940 EXPECT_TRUE(observer_.renegotiation_needed_);
1941 observer_.renegotiation_needed_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001942
1943 config.ordered = false;
1944 channel = pc_->CreateDataChannel("2", &config);
1945 EXPECT_TRUE(channel != NULL);
1946 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001947 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948
1949 config.ordered = true;
1950 config.maxRetransmits = 0;
1951 channel = pc_->CreateDataChannel("3", &config);
1952 EXPECT_TRUE(channel != NULL);
1953 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001954 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955
1956 config.maxRetransmits = -1;
1957 config.maxRetransmitTime = 0;
1958 channel = pc_->CreateDataChannel("4", &config);
1959 EXPECT_TRUE(channel != NULL);
1960 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001961 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001962}
1963
1964// This tests that no data channel is returned if both maxRetransmits and
1965// maxRetransmitTime are set for SCTP data channels.
1966TEST_F(PeerConnectionInterfaceTest,
1967 CreateSctpDataChannelShouldFailForInvalidConfig) {
1968 FakeConstraints constraints;
1969 constraints.SetAllowDtlsSctpDataChannels();
1970 CreatePeerConnection(&constraints);
1971
1972 std::string label = "test";
1973 webrtc::DataChannelInit config;
1974 config.maxRetransmits = 0;
1975 config.maxRetransmitTime = 0;
1976
zhihuang9763d562016-08-05 11:14:50 -07001977 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001978 pc_->CreateDataChannel(label, &config);
1979 EXPECT_TRUE(channel == NULL);
1980}
1981
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001982// The test verifies that creating a SCTP data channel with an id already in use
1983// or out of range should fail.
1984TEST_F(PeerConnectionInterfaceTest,
1985 CreateSctpDataChannelWithInvalidIdShouldFail) {
1986 FakeConstraints constraints;
1987 constraints.SetAllowDtlsSctpDataChannels();
1988 CreatePeerConnection(&constraints);
1989
1990 webrtc::DataChannelInit config;
zhihuang9763d562016-08-05 11:14:50 -07001991 rtc::scoped_refptr<DataChannelInterface> channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001992
wu@webrtc.orgcecfd182013-10-30 05:18:12 +00001993 config.id = 1;
1994 channel = pc_->CreateDataChannel("1", &config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001995 EXPECT_TRUE(channel != NULL);
1996 EXPECT_EQ(1, channel->id());
1997
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998 channel = pc_->CreateDataChannel("x", &config);
1999 EXPECT_TRUE(channel == NULL);
2000
2001 config.id = cricket::kMaxSctpSid;
2002 channel = pc_->CreateDataChannel("max", &config);
2003 EXPECT_TRUE(channel != NULL);
2004 EXPECT_EQ(config.id, channel->id());
2005
2006 config.id = cricket::kMaxSctpSid + 1;
2007 channel = pc_->CreateDataChannel("x", &config);
2008 EXPECT_TRUE(channel == NULL);
2009}
2010
deadbeefab9b2d12015-10-14 11:33:11 -07002011// Verifies that duplicated label is allowed for SCTP data channel.
2012TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
2013 FakeConstraints constraints;
2014 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2015 true);
2016 CreatePeerConnection(&constraints);
2017
2018 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07002019 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002020 pc_->CreateDataChannel(label, nullptr);
2021 EXPECT_NE(channel, nullptr);
2022
zhihuang9763d562016-08-05 11:14:50 -07002023 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002024 pc_->CreateDataChannel(label, nullptr);
2025 EXPECT_NE(dup_channel, nullptr);
2026}
2027
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002028// This test verifies that OnRenegotiationNeeded is fired for every new RTP
2029// DataChannel.
2030TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) {
2031 FakeConstraints constraints;
2032 constraints.SetAllowRtpDataChannels();
2033 CreatePeerConnection(&constraints);
2034
zhihuang9763d562016-08-05 11:14:50 -07002035 rtc::scoped_refptr<DataChannelInterface> dc1 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002036 pc_->CreateDataChannel("test1", NULL);
2037 EXPECT_TRUE(observer_.renegotiation_needed_);
2038 observer_.renegotiation_needed_ = false;
2039
zhihuang9763d562016-08-05 11:14:50 -07002040 rtc::scoped_refptr<DataChannelInterface> dc2 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002041 pc_->CreateDataChannel("test2", NULL);
2042 EXPECT_TRUE(observer_.renegotiation_needed_);
2043}
2044
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002045// This test that a data channel closes when a PeerConnection is deleted/closed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002046TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002047 FakeConstraints constraints;
2048 constraints.SetAllowRtpDataChannels();
2049 CreatePeerConnection(&constraints);
2050
zhihuang9763d562016-08-05 11:14:50 -07002051 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002052 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07002053 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002054 pc_->CreateDataChannel("test2", NULL);
2055 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002056 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002057 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07002058 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059 new MockDataChannelObserver(data2));
2060
2061 CreateOfferReceiveAnswer();
2062 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2063 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
2064
2065 ReleasePeerConnection();
2066 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2067 EXPECT_EQ(DataChannelInterface::kClosed, data2->state());
2068}
2069
2070// This test that data channels can be rejected in an answer.
2071TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) {
2072 FakeConstraints constraints;
2073 constraints.SetAllowRtpDataChannels();
2074 CreatePeerConnection(&constraints);
2075
zhihuang9763d562016-08-05 11:14:50 -07002076 rtc::scoped_refptr<DataChannelInterface> offer_channel(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002077 pc_->CreateDataChannel("offer_channel", NULL));
2078
2079 CreateOfferAsLocalDescription();
2080
2081 // Create an answer where the m-line for data channels are rejected.
2082 std::string sdp;
2083 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2084 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
2085 SessionDescriptionInterface::kAnswer);
2086 EXPECT_TRUE(answer->Initialize(sdp, NULL));
2087 cricket::ContentInfo* data_info =
2088 answer->description()->GetContentByName("data");
2089 data_info->rejected = true;
2090
2091 DoSetRemoteDescription(answer);
2092 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2093}
2094
2095// Test that we can create a session description from an SDP string from
2096// FireFox, use it as a remote session description, generate an answer and use
2097// the answer as a local description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002098TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002099 FakeConstraints constraints;
2100 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2101 true);
2102 CreatePeerConnection(&constraints);
2103 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2104 SessionDescriptionInterface* desc =
2105 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002106 webrtc::kFireFoxSdpOffer, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002107 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2108 CreateAnswerAsLocalDescription();
2109 ASSERT_TRUE(pc_->local_description() != NULL);
2110 ASSERT_TRUE(pc_->remote_description() != NULL);
2111
2112 const cricket::ContentInfo* content =
2113 cricket::GetFirstAudioContent(pc_->local_description()->description());
2114 ASSERT_TRUE(content != NULL);
2115 EXPECT_FALSE(content->rejected);
2116
2117 content =
2118 cricket::GetFirstVideoContent(pc_->local_description()->description());
2119 ASSERT_TRUE(content != NULL);
2120 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002121#ifdef HAVE_SCTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122 content =
2123 cricket::GetFirstDataContent(pc_->local_description()->description());
2124 ASSERT_TRUE(content != NULL);
2125 EXPECT_TRUE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002126#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127}
2128
deadbeef8662f942017-01-20 21:20:51 -08002129// Test that an offer can be received which offers DTLS with SDES fallback.
2130// Regression test for issue:
2131// https://bugs.chromium.org/p/webrtc/issues/detail?id=6972
2132TEST_F(PeerConnectionInterfaceTest, ReceiveDtlsSdesFallbackOffer) {
2133 FakeConstraints constraints;
2134 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2135 true);
2136 CreatePeerConnection(&constraints);
2137 // Wait for fake certificate to be generated. Previously, this is what caused
2138 // the "a=crypto" lines to be rejected.
2139 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2140 ASSERT_NE(nullptr, fake_certificate_generator_);
2141 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2142 kTimeout);
2143 SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
2144 SessionDescriptionInterface::kOffer, kDtlsSdesFallbackSdp, nullptr);
2145 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2146 CreateAnswerAsLocalDescription();
2147}
2148
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002149// Test that we can create an audio only offer and receive an answer with a
2150// limited set of audio codecs and receive an updated offer with more audio
2151// codecs, where the added codecs are not supported.
2152TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
deadbeef293e9262017-01-11 12:28:30 -08002153 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002154 AddVoiceStream("audio_label");
2155 CreateOfferAsLocalDescription();
2156
2157 SessionDescriptionInterface* answer =
2158 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
jbauchfabe2c92015-07-16 13:43:14 -07002159 webrtc::kAudioSdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002160 EXPECT_TRUE(DoSetSessionDescription(answer, false));
2161
2162 SessionDescriptionInterface* updated_offer =
2163 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002164 webrtc::kAudioSdpWithUnsupportedCodecs,
2165 nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false));
2167 CreateAnswerAsLocalDescription();
2168}
2169
deadbeefc80741f2015-10-22 13:14:45 -07002170// Test that if we're receiving (but not sending) a track, subsequent offers
2171// will have m-lines with a=recvonly.
2172TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
2173 FakeConstraints constraints;
2174 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2175 true);
2176 CreatePeerConnection(&constraints);
2177 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2178 CreateAnswerAsLocalDescription();
2179
2180 // At this point we should be receiving stream 1, but not sending anything.
2181 // A new offer should be recvonly.
kwibergd1fe2812016-04-27 06:47:29 -07002182 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002183 DoCreateOffer(&offer, nullptr);
2184
2185 const cricket::ContentInfo* video_content =
2186 cricket::GetFirstVideoContent(offer->description());
2187 const cricket::VideoContentDescription* video_desc =
2188 static_cast<const cricket::VideoContentDescription*>(
2189 video_content->description);
2190 ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction());
2191
2192 const cricket::ContentInfo* audio_content =
2193 cricket::GetFirstAudioContent(offer->description());
2194 const cricket::AudioContentDescription* audio_desc =
2195 static_cast<const cricket::AudioContentDescription*>(
2196 audio_content->description);
2197 ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction());
2198}
2199
2200// Test that if we're receiving (but not sending) a track, and the
2201// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2202// false, the generated m-lines will be a=inactive.
2203TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
2204 FakeConstraints constraints;
2205 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2206 true);
2207 CreatePeerConnection(&constraints);
2208 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2209 CreateAnswerAsLocalDescription();
2210
2211 // At this point we should be receiving stream 1, but not sending anything.
2212 // A new offer would be recvonly, but we'll set the "no receive" constraints
2213 // to make it inactive.
kwibergd1fe2812016-04-27 06:47:29 -07002214 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002215 FakeConstraints offer_constraints;
2216 offer_constraints.AddMandatory(
2217 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false);
2218 offer_constraints.AddMandatory(
2219 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false);
2220 DoCreateOffer(&offer, &offer_constraints);
2221
2222 const cricket::ContentInfo* video_content =
2223 cricket::GetFirstVideoContent(offer->description());
2224 const cricket::VideoContentDescription* video_desc =
2225 static_cast<const cricket::VideoContentDescription*>(
2226 video_content->description);
2227 ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction());
2228
2229 const cricket::ContentInfo* audio_content =
2230 cricket::GetFirstAudioContent(offer->description());
2231 const cricket::AudioContentDescription* audio_desc =
2232 static_cast<const cricket::AudioContentDescription*>(
2233 audio_content->description);
2234 ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction());
2235}
2236
deadbeef653b8e02015-11-11 12:55:10 -08002237// Test that we can use SetConfiguration to change the ICE servers of the
2238// PortAllocator.
2239TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
2240 CreatePeerConnection();
2241
2242 PeerConnectionInterface::RTCConfiguration config;
2243 PeerConnectionInterface::IceServer server;
2244 server.uri = "stun:test_hostname";
2245 config.servers.push_back(server);
2246 EXPECT_TRUE(pc_->SetConfiguration(config));
2247
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08002248 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2249 EXPECT_EQ("test_hostname",
2250 port_allocator_->stun_servers().begin()->hostname());
deadbeef653b8e02015-11-11 12:55:10 -08002251}
2252
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002253TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
2254 CreatePeerConnection();
2255 PeerConnectionInterface::RTCConfiguration config;
2256 config.type = PeerConnectionInterface::kRelay;
2257 EXPECT_TRUE(pc_->SetConfiguration(config));
2258 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2259}
2260
deadbeef293e9262017-01-11 12:28:30 -08002261TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
2262 PeerConnectionInterface::RTCConfiguration config;
2263 config.prune_turn_ports = false;
2264 CreatePeerConnection(config, nullptr);
2265 EXPECT_FALSE(port_allocator_->prune_turn_ports());
2266
2267 config.prune_turn_ports = true;
2268 EXPECT_TRUE(pc_->SetConfiguration(config));
2269 EXPECT_TRUE(port_allocator_->prune_turn_ports());
2270}
2271
skvladd1f5fda2017-02-03 16:54:05 -08002272// Test that the ice check interval can be changed. This does not verify that
2273// the setting makes it all the way to P2PTransportChannel, as that would
2274// require a very complex set of mocks.
2275TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
2276 PeerConnectionInterface::RTCConfiguration config;
2277 config.ice_check_min_interval = rtc::Optional<int>();
2278 CreatePeerConnection(config, nullptr);
2279 config.ice_check_min_interval = rtc::Optional<int>(100);
2280 EXPECT_TRUE(pc_->SetConfiguration(config));
2281 PeerConnectionInterface::RTCConfiguration new_config =
2282 pc_->GetConfiguration();
2283 EXPECT_EQ(new_config.ice_check_min_interval, rtc::Optional<int>(100));
2284}
2285
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002286// Test that when SetConfiguration changes both the pool size and other
2287// attributes, the pooled session is created with the updated attributes.
2288TEST_F(PeerConnectionInterfaceTest,
2289 SetConfigurationCreatesPooledSessionCorrectly) {
2290 CreatePeerConnection();
2291 PeerConnectionInterface::RTCConfiguration config;
2292 config.ice_candidate_pool_size = 1;
2293 PeerConnectionInterface::IceServer server;
2294 server.uri = kStunAddressOnly;
2295 config.servers.push_back(server);
2296 config.type = PeerConnectionInterface::kRelay;
Taylor Brandstetter417eebe2016-05-23 16:02:19 -07002297 EXPECT_TRUE(pc_->SetConfiguration(config));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002298
2299 const cricket::FakePortAllocatorSession* session =
2300 static_cast<const cricket::FakePortAllocatorSession*>(
2301 port_allocator_->GetPooledSession());
2302 ASSERT_NE(nullptr, session);
2303 EXPECT_EQ(1UL, session->stun_servers().size());
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002304}
2305
deadbeef293e9262017-01-11 12:28:30 -08002306// Test that after SetLocalDescription, changing the pool size is not allowed,
2307// and an invalid modification error is returned.
deadbeef6de92f92016-12-12 18:49:32 -08002308TEST_F(PeerConnectionInterfaceTest,
2309 CantChangePoolSizeAfterSetLocalDescription) {
2310 CreatePeerConnection();
2311 // Start by setting a size of 1.
2312 PeerConnectionInterface::RTCConfiguration config;
2313 config.ice_candidate_pool_size = 1;
2314 EXPECT_TRUE(pc_->SetConfiguration(config));
2315
2316 // Set remote offer; can still change pool size at this point.
2317 CreateOfferAsRemoteDescription();
2318 config.ice_candidate_pool_size = 2;
2319 EXPECT_TRUE(pc_->SetConfiguration(config));
2320
2321 // Set local answer; now it's too late.
2322 CreateAnswerAsLocalDescription();
2323 config.ice_candidate_pool_size = 3;
deadbeef293e9262017-01-11 12:28:30 -08002324 RTCError error;
2325 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2326 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2327}
2328
deadbeef42a42632017-03-10 15:18:00 -08002329// Test that after setting an answer, extra pooled sessions are discarded. The
2330// ICE candidate pool is only intended to be used for the first offer/answer.
2331TEST_F(PeerConnectionInterfaceTest,
2332 ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
2333 CreatePeerConnection();
2334
2335 // Set a larger-than-necessary size.
2336 PeerConnectionInterface::RTCConfiguration config;
2337 config.ice_candidate_pool_size = 4;
2338 EXPECT_TRUE(pc_->SetConfiguration(config));
2339
2340 // Do offer/answer.
2341 CreateOfferAsRemoteDescription();
2342 CreateAnswerAsLocalDescription();
2343
2344 // Expect no pooled sessions to be left.
2345 const cricket::PortAllocatorSession* session =
2346 port_allocator_->GetPooledSession();
2347 EXPECT_EQ(nullptr, session);
2348}
2349
2350// After Close is called, pooled candidates should be discarded so as to not
2351// waste network resources.
2352TEST_F(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
2353 CreatePeerConnection();
2354
2355 PeerConnectionInterface::RTCConfiguration config;
2356 config.ice_candidate_pool_size = 3;
2357 EXPECT_TRUE(pc_->SetConfiguration(config));
2358 pc_->Close();
2359
2360 // Expect no pooled sessions to be left.
2361 const cricket::PortAllocatorSession* session =
2362 port_allocator_->GetPooledSession();
2363 EXPECT_EQ(nullptr, session);
2364}
2365
deadbeef293e9262017-01-11 12:28:30 -08002366// Test that SetConfiguration returns an invalid modification error if
2367// modifying a field in the configuration that isn't allowed to be modified.
2368TEST_F(PeerConnectionInterfaceTest,
2369 SetConfigurationReturnsInvalidModificationError) {
2370 PeerConnectionInterface::RTCConfiguration config;
2371 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2372 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2373 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
2374 CreatePeerConnection(config, nullptr);
2375
2376 PeerConnectionInterface::RTCConfiguration modified_config = config;
2377 modified_config.bundle_policy =
2378 PeerConnectionInterface::kBundlePolicyMaxBundle;
2379 RTCError error;
2380 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2381 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2382
2383 modified_config = config;
2384 modified_config.rtcp_mux_policy =
2385 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2386 error.set_type(RTCErrorType::NONE);
2387 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2388 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2389
2390 modified_config = config;
2391 modified_config.continual_gathering_policy =
2392 PeerConnectionInterface::GATHER_CONTINUALLY;
2393 error.set_type(RTCErrorType::NONE);
2394 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2395 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2396}
2397
2398// Test that SetConfiguration returns a range error if the candidate pool size
2399// is negative or larger than allowed by the spec.
2400TEST_F(PeerConnectionInterfaceTest,
2401 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2402 PeerConnectionInterface::RTCConfiguration config;
2403 CreatePeerConnection(config, nullptr);
2404
2405 config.ice_candidate_pool_size = -1;
2406 RTCError error;
2407 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2408 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2409
2410 config.ice_candidate_pool_size = INT_MAX;
2411 error.set_type(RTCErrorType::NONE);
2412 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2413 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2414}
2415
2416// Test that SetConfiguration returns a syntax error if parsing an ICE server
2417// URL failed.
2418TEST_F(PeerConnectionInterfaceTest,
2419 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2420 PeerConnectionInterface::RTCConfiguration config;
2421 CreatePeerConnection(config, nullptr);
2422
2423 PeerConnectionInterface::IceServer bad_server;
2424 bad_server.uri = "stunn:www.example.com";
2425 config.servers.push_back(bad_server);
2426 RTCError error;
2427 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2428 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2429}
2430
2431// Test that SetConfiguration returns an invalid parameter error if a TURN
2432// IceServer is missing a username or password.
2433TEST_F(PeerConnectionInterfaceTest,
2434 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2435 PeerConnectionInterface::RTCConfiguration config;
2436 CreatePeerConnection(config, nullptr);
2437
2438 PeerConnectionInterface::IceServer bad_server;
2439 bad_server.uri = "turn:www.example.com";
2440 // Missing password.
2441 bad_server.username = "foo";
2442 config.servers.push_back(bad_server);
2443 RTCError error;
2444 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2445 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
deadbeef6de92f92016-12-12 18:49:32 -08002446}
2447
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448// Test that PeerConnection::Close changes the states to closed and all remote
2449// tracks change state to ended.
2450TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
2451 // Initialize a PeerConnection and negotiate local and remote session
2452 // description.
2453 InitiateCall();
2454 ASSERT_EQ(1u, pc_->local_streams()->count());
2455 ASSERT_EQ(1u, pc_->remote_streams()->count());
2456
2457 pc_->Close();
2458
2459 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2460 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2461 pc_->ice_connection_state());
2462 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2463 pc_->ice_gathering_state());
2464
2465 EXPECT_EQ(1u, pc_->local_streams()->count());
2466 EXPECT_EQ(1u, pc_->remote_streams()->count());
2467
zhihuang9763d562016-08-05 11:14:50 -07002468 rtc::scoped_refptr<MediaStreamInterface> remote_stream =
2469 pc_->remote_streams()->at(0);
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002470 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002471 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002472 remote_stream->GetAudioTracks()[0]->state(), kTimeout);
2473 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2474 remote_stream->GetVideoTracks()[0]->state(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475}
2476
2477// Test that PeerConnection methods fails gracefully after
2478// PeerConnection::Close has been called.
2479TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) {
deadbeef293e9262017-01-11 12:28:30 -08002480 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2482 CreateOfferAsRemoteDescription();
2483 CreateAnswerAsLocalDescription();
2484
2485 ASSERT_EQ(1u, pc_->local_streams()->count());
zhihuang9763d562016-08-05 11:14:50 -07002486 rtc::scoped_refptr<MediaStreamInterface> local_stream =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487 pc_->local_streams()->at(0);
2488
2489 pc_->Close();
2490
2491 pc_->RemoveStream(local_stream);
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00002492 EXPECT_FALSE(pc_->AddStream(local_stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002493
2494 ASSERT_FALSE(local_stream->GetAudioTracks().empty());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002495 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0]));
wu@webrtc.org66037362013-08-13 00:09:35 +00002497 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498
2499 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL);
2500
2501 EXPECT_TRUE(pc_->local_description() != NULL);
2502 EXPECT_TRUE(pc_->remote_description() != NULL);
2503
kwibergd1fe2812016-04-27 06:47:29 -07002504 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07002505 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwibergd1fe2812016-04-27 06:47:29 -07002506 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07002507 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508
2509 std::string sdp;
2510 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
2511 SessionDescriptionInterface* remote_offer =
2512 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2513 sdp, NULL);
2514 EXPECT_FALSE(DoSetRemoteDescription(remote_offer));
2515
2516 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
2517 SessionDescriptionInterface* local_offer =
2518 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2519 sdp, NULL);
2520 EXPECT_FALSE(DoSetLocalDescription(local_offer));
2521}
2522
2523// Test that GetStats can still be called after PeerConnection::Close.
2524TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) {
2525 InitiateCall();
2526 pc_->Close();
2527 DoGetStats(NULL);
2528}
deadbeefab9b2d12015-10-14 11:33:11 -07002529
2530// NOTE: The series of tests below come from what used to be
2531// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2532// setting a remote or local description has the expected effects.
2533
2534// This test verifies that the remote MediaStreams corresponding to a received
2535// SDP string is created. In this test the two separate MediaStreams are
2536// signaled.
2537TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
2538 FakeConstraints constraints;
2539 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2540 true);
2541 CreatePeerConnection(&constraints);
2542 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2543
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002544 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002545 EXPECT_TRUE(
2546 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2547 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2548 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2549
2550 // Create a session description based on another SDP with another
2551 // MediaStream.
2552 CreateAndSetRemoteOffer(kSdpStringWithStream1And2);
2553
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002554 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002555 EXPECT_TRUE(
2556 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2557}
2558
2559// This test verifies that when remote tracks are added/removed from SDP, the
2560// created remote streams are updated appropriately.
2561TEST_F(PeerConnectionInterfaceTest,
2562 AddRemoveTrackFromExistingRemoteMediaStream) {
2563 FakeConstraints constraints;
2564 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2565 true);
2566 CreatePeerConnection(&constraints);
kwibergd1fe2812016-04-27 06:47:29 -07002567 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
kwiberg2bbff992016-03-16 11:03:04 -07002568 CreateSessionDescriptionAndReference(1, 1);
deadbeefab9b2d12015-10-14 11:33:11 -07002569 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release()));
2570 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2571 reference_collection_));
2572
2573 // Add extra audio and video tracks to the same MediaStream.
kwibergd1fe2812016-04-27 06:47:29 -07002574 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
kwiberg2bbff992016-03-16 11:03:04 -07002575 CreateSessionDescriptionAndReference(2, 2);
deadbeefab9b2d12015-10-14 11:33:11 -07002576 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release()));
2577 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2578 reference_collection_));
zhihuang9763d562016-08-05 11:14:50 -07002579 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
perkjd61bf802016-03-24 03:16:19 -07002580 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2581 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
zhihuang9763d562016-08-05 11:14:50 -07002582 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
perkjd61bf802016-03-24 03:16:19 -07002583 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2584 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002585
2586 // Remove the extra audio and video tracks.
kwibergd1fe2812016-04-27 06:47:29 -07002587 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
kwiberg2bbff992016-03-16 11:03:04 -07002588 CreateSessionDescriptionAndReference(1, 1);
perkjd61bf802016-03-24 03:16:19 -07002589 MockTrackObserver audio_track_observer(audio_track2);
2590 MockTrackObserver video_track_observer(video_track2);
2591
2592 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2593 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
deadbeefab9b2d12015-10-14 11:33:11 -07002594 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release()));
2595 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2596 reference_collection_));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002597 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002598 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002599 audio_track2->state(), kTimeout);
2600 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2601 video_track2->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002602}
2603
2604// This tests that remote tracks are ended if a local session description is set
2605// that rejects the media content type.
2606TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) {
2607 FakeConstraints constraints;
2608 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2609 true);
2610 CreatePeerConnection(&constraints);
2611 // First create and set a remote offer, then reject its video content in our
2612 // answer.
2613 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2614 ASSERT_EQ(1u, observer_.remote_streams()->count());
2615 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2616 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2617 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2618
2619 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video =
2620 remote_stream->GetVideoTracks()[0];
2621 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state());
2622 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio =
2623 remote_stream->GetAudioTracks()[0];
2624 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2625
kwibergd1fe2812016-04-27 06:47:29 -07002626 std::unique_ptr<SessionDescriptionInterface> local_answer;
kwiberg2bbff992016-03-16 11:03:04 -07002627 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002628 cricket::ContentInfo* video_info =
2629 local_answer->description()->GetContentByName("video");
2630 video_info->rejected = true;
2631 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2632 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state());
2633 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2634
2635 // Now create an offer where we reject both video and audio.
kwibergd1fe2812016-04-27 06:47:29 -07002636 std::unique_ptr<SessionDescriptionInterface> local_offer;
kwiberg2bbff992016-03-16 11:03:04 -07002637 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002638 video_info = local_offer->description()->GetContentByName("video");
2639 ASSERT_TRUE(video_info != nullptr);
2640 video_info->rejected = true;
2641 cricket::ContentInfo* audio_info =
2642 local_offer->description()->GetContentByName("audio");
2643 ASSERT_TRUE(audio_info != nullptr);
2644 audio_info->rejected = true;
2645 EXPECT_TRUE(DoSetLocalDescription(local_offer.release()));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002646 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002647 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002648 remote_audio->state(), kTimeout);
2649 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2650 remote_video->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002651}
2652
2653// This tests that we won't crash if the remote track has been removed outside
2654// of PeerConnection and then PeerConnection tries to reject the track.
2655TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) {
2656 FakeConstraints constraints;
2657 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2658 true);
2659 CreatePeerConnection(&constraints);
2660 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2661 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2662 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2663 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2664
kwibergd1fe2812016-04-27 06:47:29 -07002665 std::unique_ptr<SessionDescriptionInterface> local_answer(
deadbeefab9b2d12015-10-14 11:33:11 -07002666 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
2667 kSdpStringWithStream1, nullptr));
2668 cricket::ContentInfo* video_info =
2669 local_answer->description()->GetContentByName("video");
2670 video_info->rejected = true;
2671 cricket::ContentInfo* audio_info =
2672 local_answer->description()->GetContentByName("audio");
2673 audio_info->rejected = true;
2674 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2675
2676 // No crash is a pass.
2677}
2678
deadbeef5e97fb52015-10-15 12:49:08 -07002679// This tests that if a recvonly remote description is set, no remote streams
2680// will be created, even if the description contains SSRCs/MSIDs.
2681// See: https://code.google.com/p/webrtc/issues/detail?id=5054
2682TEST_F(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
2683 FakeConstraints constraints;
2684 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2685 true);
2686 CreatePeerConnection(&constraints);
2687
2688 std::string recvonly_offer = kSdpStringWithStream1;
2689 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly,
2690 strlen(kRecvonly), &recvonly_offer);
2691 CreateAndSetRemoteOffer(recvonly_offer);
2692
2693 EXPECT_EQ(0u, observer_.remote_streams()->count());
2694}
2695
deadbeefab9b2d12015-10-14 11:33:11 -07002696// This tests that a default MediaStream is created if a remote session
2697// description doesn't contain any streams and no MSID support.
2698// It also tests that the default stream is updated if a video m-line is added
2699// in a subsequent session description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002700TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002701 FakeConstraints constraints;
2702 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2703 true);
2704 CreatePeerConnection(&constraints);
2705 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2706
2707 ASSERT_EQ(1u, observer_.remote_streams()->count());
2708 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2709
2710 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2711 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
2712 EXPECT_EQ("default", remote_stream->label());
2713
2714 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2715 ASSERT_EQ(1u, observer_.remote_streams()->count());
2716 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2717 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002718 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2719 remote_stream->GetAudioTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002720 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2721 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002722 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2723 remote_stream->GetVideoTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002724}
2725
2726// This tests that a default MediaStream is created if a remote session
2727// description doesn't contain any streams and media direction is send only.
2728TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002729 SendOnlySdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002730 FakeConstraints constraints;
2731 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2732 true);
2733 CreatePeerConnection(&constraints);
2734 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2735
2736 ASSERT_EQ(1u, observer_.remote_streams()->count());
2737 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2738
2739 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2740 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2741 EXPECT_EQ("default", remote_stream->label());
2742}
2743
2744// This tests that it won't crash when PeerConnection tries to remove
2745// a remote track that as already been removed from the MediaStream.
2746TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) {
2747 FakeConstraints constraints;
2748 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2749 true);
2750 CreatePeerConnection(&constraints);
2751 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2752 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2753 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2754 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2755
2756 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2757
2758 // No crash is a pass.
2759}
2760
2761// This tests that a default MediaStream is created if the remote session
2762// description doesn't contain any streams and don't contain an indication if
2763// MSID is supported.
2764TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002765 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002766 FakeConstraints constraints;
2767 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2768 true);
2769 CreatePeerConnection(&constraints);
2770 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2771
2772 ASSERT_EQ(1u, observer_.remote_streams()->count());
2773 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2774 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2775 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2776}
2777
2778// This tests that a default MediaStream is not created if the remote session
2779// description doesn't contain any streams but does support MSID.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002780TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002781 FakeConstraints constraints;
2782 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2783 true);
2784 CreatePeerConnection(&constraints);
2785 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2786 EXPECT_EQ(0u, observer_.remote_streams()->count());
2787}
2788
deadbeefbda7e0b2015-12-08 17:13:40 -08002789// This tests that when setting a new description, the old default tracks are
2790// not destroyed and recreated.
2791// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
Stefan Holmer102362b2016-03-18 09:39:07 +01002792TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002793 DefaultTracksNotDestroyedAndRecreated) {
deadbeefbda7e0b2015-12-08 17:13:40 -08002794 FakeConstraints constraints;
2795 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2796 true);
2797 CreatePeerConnection(&constraints);
2798 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2799
2800 ASSERT_EQ(1u, observer_.remote_streams()->count());
2801 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2802 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2803
2804 // Set the track to "disabled", then set a new description and ensure the
2805 // track is still disabled, which ensures it hasn't been recreated.
2806 remote_stream->GetAudioTracks()[0]->set_enabled(false);
2807 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2808 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2809 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
2810}
2811
deadbeefab9b2d12015-10-14 11:33:11 -07002812// This tests that a default MediaStream is not created if a remote session
2813// description is updated to not have any MediaStreams.
2814TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) {
2815 FakeConstraints constraints;
2816 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2817 true);
2818 CreatePeerConnection(&constraints);
2819 CreateAndSetRemoteOffer(kSdpStringWithStream1);
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002820 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002821 EXPECT_TRUE(
2822 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2823
2824 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2825 EXPECT_EQ(0u, observer_.remote_streams()->count());
2826}
2827
2828// This tests that an RtpSender is created when the local description is set
2829// after adding a local stream.
2830// TODO(deadbeef): This test and the one below it need to be updated when
2831// an RtpSender's lifetime isn't determined by when a local description is set.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002832TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002833 FakeConstraints constraints;
2834 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2835 true);
2836 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002837
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002838 // Create an offer with 1 stream with 2 tracks of each type.
2839 rtc::scoped_refptr<StreamCollection> stream_collection =
2840 CreateStreamCollection(1, 2);
2841 pc_->AddStream(stream_collection->at(0));
2842 std::unique_ptr<SessionDescriptionInterface> offer;
2843 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2844 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002845
deadbeefab9b2d12015-10-14 11:33:11 -07002846 auto senders = pc_->GetSenders();
2847 EXPECT_EQ(4u, senders.size());
2848 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2849 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2850 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2851 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2852
2853 // Remove an audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002854 pc_->RemoveStream(stream_collection->at(0));
2855 stream_collection = CreateStreamCollection(1, 1);
2856 pc_->AddStream(stream_collection->at(0));
2857 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2858 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
2859
deadbeefab9b2d12015-10-14 11:33:11 -07002860 senders = pc_->GetSenders();
2861 EXPECT_EQ(2u, senders.size());
2862 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2863 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2864 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
2865 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
2866}
2867
2868// This tests that an RtpSender is created when the local description is set
2869// before adding a local stream.
2870TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002871 AddLocalStreamAfterLocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002872 FakeConstraints constraints;
2873 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2874 true);
2875 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002876
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002877 rtc::scoped_refptr<StreamCollection> stream_collection =
2878 CreateStreamCollection(1, 2);
2879 // Add a stream to create the offer, but remove it afterwards.
2880 pc_->AddStream(stream_collection->at(0));
2881 std::unique_ptr<SessionDescriptionInterface> offer;
2882 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2883 pc_->RemoveStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002884
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002885 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002886 auto senders = pc_->GetSenders();
2887 EXPECT_EQ(0u, senders.size());
2888
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002889 pc_->AddStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002890 senders = pc_->GetSenders();
2891 EXPECT_EQ(4u, senders.size());
2892 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2893 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2894 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2895 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2896}
2897
2898// This tests that the expected behavior occurs if the SSRC on a local track is
2899// changed when SetLocalDescription is called.
2900TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002901 ChangeSsrcOnTrackInLocalSessionDescription) {
deadbeefab9b2d12015-10-14 11:33:11 -07002902 FakeConstraints constraints;
2903 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2904 true);
2905 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002906
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002907 rtc::scoped_refptr<StreamCollection> stream_collection =
2908 CreateStreamCollection(2, 1);
2909 pc_->AddStream(stream_collection->at(0));
2910 std::unique_ptr<SessionDescriptionInterface> offer;
2911 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2912 // Grab a copy of the offer before it gets passed into the PC.
2913 std::unique_ptr<JsepSessionDescription> modified_offer(
2914 new JsepSessionDescription(JsepSessionDescription::kOffer));
2915 modified_offer->Initialize(offer->description()->Copy(), offer->session_id(),
2916 offer->session_version());
2917 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002918
deadbeefab9b2d12015-10-14 11:33:11 -07002919 auto senders = pc_->GetSenders();
2920 EXPECT_EQ(2u, senders.size());
2921 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2922 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2923
2924 // Change the ssrc of the audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002925 cricket::MediaContentDescription* desc =
2926 cricket::GetFirstAudioContentDescription(modified_offer->description());
2927 ASSERT_TRUE(desc != NULL);
2928 for (StreamParams& stream : desc->mutable_streams()) {
2929 for (unsigned int& ssrc : stream.ssrcs) {
2930 ++ssrc;
2931 }
2932 }
deadbeefab9b2d12015-10-14 11:33:11 -07002933
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002934 desc =
2935 cricket::GetFirstVideoContentDescription(modified_offer->description());
2936 ASSERT_TRUE(desc != NULL);
2937 for (StreamParams& stream : desc->mutable_streams()) {
2938 for (unsigned int& ssrc : stream.ssrcs) {
2939 ++ssrc;
2940 }
2941 }
2942
2943 EXPECT_TRUE(DoSetLocalDescription(modified_offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002944 senders = pc_->GetSenders();
2945 EXPECT_EQ(2u, senders.size());
2946 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2947 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2948 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
2949 // changed.
2950}
2951
2952// This tests that the expected behavior occurs if a new session description is
2953// set with the same tracks, but on a different MediaStream.
Stefan Holmer55d6e7c2016-03-17 16:26:40 +01002954TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002955 SignalSameTracksInSeparateMediaStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002956 FakeConstraints constraints;
2957 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2958 true);
2959 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002960
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002961 rtc::scoped_refptr<StreamCollection> stream_collection =
2962 CreateStreamCollection(2, 1);
2963 pc_->AddStream(stream_collection->at(0));
2964 std::unique_ptr<SessionDescriptionInterface> offer;
2965 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2966 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002967
deadbeefab9b2d12015-10-14 11:33:11 -07002968 auto senders = pc_->GetSenders();
2969 EXPECT_EQ(2u, senders.size());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002970 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
2971 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
deadbeefab9b2d12015-10-14 11:33:11 -07002972
2973 // Add a new MediaStream but with the same tracks as in the first stream.
2974 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
2975 webrtc::MediaStream::Create(kStreams[1]));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002976 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
2977 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
deadbeefab9b2d12015-10-14 11:33:11 -07002978 pc_->AddStream(stream_1);
2979
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002980 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2981 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002982
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002983 auto new_senders = pc_->GetSenders();
2984 // Should be the same senders as before, but with updated stream id.
2985 // Note that this behavior is subject to change in the future.
2986 // We may decide the PC should ignore existing tracks in AddStream.
2987 EXPECT_EQ(senders, new_senders);
2988 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
2989 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
deadbeefab9b2d12015-10-14 11:33:11 -07002990}
2991
zhihuang81c3a032016-11-17 12:06:24 -08002992// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
2993TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
2994 FakeConstraints constraints;
2995 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2996 true);
2997 CreatePeerConnection(&constraints);
2998 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
2999 EXPECT_EQ(observer_.num_added_tracks_, 1);
3000 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
3001
3002 // Create and set the updated remote SDP.
3003 CreateAndSetRemoteOffer(kSdpStringWithStream1);
3004 EXPECT_EQ(observer_.num_added_tracks_, 2);
3005 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
3006}
3007
deadbeefd1a38b52016-12-10 13:15:33 -08003008// Test that when SetConfiguration is called and the configuration is
3009// changing, the next offer causes an ICE restart.
3010TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingIceRetart) {
3011 PeerConnectionInterface::RTCConfiguration config;
3012 config.type = PeerConnectionInterface::kRelay;
3013 // Need to pass default constraints to prevent disabling of DTLS...
3014 FakeConstraints default_constraints;
3015 CreatePeerConnection(config, &default_constraints);
3016 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3017
3018 // Do initial offer/answer so there's something to restart.
3019 CreateOfferAsLocalDescription();
3020 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3021
3022 // Grab the ufrags.
3023 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3024
3025 // Change ICE policy, which should trigger an ICE restart on the next offer.
3026 config.type = PeerConnectionInterface::kAll;
3027 EXPECT_TRUE(pc_->SetConfiguration(config));
3028 CreateOfferAsLocalDescription();
3029
3030 // Grab the new ufrags.
3031 std::vector<std::string> subsequent_ufrags =
3032 GetUfrags(pc_->local_description());
3033
3034 // Sanity check.
3035 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
3036 // Check that each ufrag is different.
3037 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
3038 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
3039 }
3040}
3041
3042// Test that when SetConfiguration is called and the configuration *isn't*
3043// changing, the next offer does *not* cause an ICE restart.
3044TEST_F(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRetart) {
3045 PeerConnectionInterface::RTCConfiguration config;
3046 config.type = PeerConnectionInterface::kRelay;
3047 // Need to pass default constraints to prevent disabling of DTLS...
3048 FakeConstraints default_constraints;
3049 CreatePeerConnection(config, &default_constraints);
3050 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3051
3052 // Do initial offer/answer so there's something to restart.
3053 CreateOfferAsLocalDescription();
3054 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3055
3056 // Grab the ufrags.
3057 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3058
3059 // Call SetConfiguration with a config identical to what the PC was
3060 // constructed with.
3061 EXPECT_TRUE(pc_->SetConfiguration(config));
3062 CreateOfferAsLocalDescription();
3063
3064 // Grab the new ufrags.
3065 std::vector<std::string> subsequent_ufrags =
3066 GetUfrags(pc_->local_description());
3067
3068 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
3069}
3070
3071// Test for a weird corner case scenario:
3072// 1. Audio/video session established.
3073// 2. SetConfiguration changes ICE config; ICE restart needed.
3074// 3. ICE restart initiated by remote peer, but only for one m= section.
3075// 4. Next createOffer should initiate an ICE restart, but only for the other
3076// m= section; it would be pointless to do an ICE restart for the m= section
3077// that was already restarted.
3078TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
3079 PeerConnectionInterface::RTCConfiguration config;
3080 config.type = PeerConnectionInterface::kRelay;
3081 // Need to pass default constraints to prevent disabling of DTLS...
3082 FakeConstraints default_constraints;
3083 CreatePeerConnection(config, &default_constraints);
3084 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3085
3086 // Do initial offer/answer so there's something to restart.
3087 CreateOfferAsLocalDescription();
3088 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3089
3090 // Change ICE policy, which should set the "needs-ice-restart" flag.
3091 config.type = PeerConnectionInterface::kAll;
3092 EXPECT_TRUE(pc_->SetConfiguration(config));
3093
3094 // Do ICE restart for the first m= section, initiated by remote peer.
3095 webrtc::JsepSessionDescription* remote_offer =
3096 new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer);
3097 EXPECT_TRUE(remote_offer->Initialize(kSdpStringWithStream1, nullptr));
3098 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3099 "modified";
3100 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3101 CreateAnswerAsLocalDescription();
3102
3103 // Grab the ufrags.
3104 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3105 ASSERT_EQ(2, initial_ufrags.size());
3106
3107 // Create offer and grab the new ufrags.
3108 CreateOfferAsLocalDescription();
3109 std::vector<std::string> subsequent_ufrags =
3110 GetUfrags(pc_->local_description());
3111 ASSERT_EQ(2, subsequent_ufrags.size());
3112
3113 // Ensure that only the ufrag for the second m= section changed.
3114 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3115 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3116}
3117
deadbeeffe4a8a42016-12-20 17:56:17 -08003118// Tests that the methods to return current/pending descriptions work as
3119// expected at different points in the offer/answer exchange. This test does
3120// one offer/answer exchange as the offerer, then another as the answerer.
3121TEST_F(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
3122 // This disables DTLS so we can apply an answer to ourselves.
3123 CreatePeerConnection();
3124
3125 // Create initial local offer and get SDP (which will also be used as
3126 // answer/pranswer);
3127 std::unique_ptr<SessionDescriptionInterface> offer;
3128 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3129 std::string sdp;
3130 EXPECT_TRUE(offer->ToString(&sdp));
3131
3132 // Set local offer.
3133 SessionDescriptionInterface* local_offer = offer.release();
3134 EXPECT_TRUE(DoSetLocalDescription(local_offer));
3135 EXPECT_EQ(local_offer, pc_->pending_local_description());
3136 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3137 EXPECT_EQ(nullptr, pc_->current_local_description());
3138 EXPECT_EQ(nullptr, pc_->current_remote_description());
3139
3140 // Set remote pranswer.
3141 SessionDescriptionInterface* remote_pranswer =
3142 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3143 sdp, nullptr);
3144 EXPECT_TRUE(DoSetRemoteDescription(remote_pranswer));
3145 EXPECT_EQ(local_offer, pc_->pending_local_description());
3146 EXPECT_EQ(remote_pranswer, pc_->pending_remote_description());
3147 EXPECT_EQ(nullptr, pc_->current_local_description());
3148 EXPECT_EQ(nullptr, pc_->current_remote_description());
3149
3150 // Set remote answer.
3151 SessionDescriptionInterface* remote_answer = webrtc::CreateSessionDescription(
3152 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3153 EXPECT_TRUE(DoSetRemoteDescription(remote_answer));
3154 EXPECT_EQ(nullptr, pc_->pending_local_description());
3155 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3156 EXPECT_EQ(local_offer, pc_->current_local_description());
3157 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3158
3159 // Set remote offer.
3160 SessionDescriptionInterface* remote_offer = webrtc::CreateSessionDescription(
3161 SessionDescriptionInterface::kOffer, sdp, nullptr);
3162 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3163 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3164 EXPECT_EQ(nullptr, pc_->pending_local_description());
3165 EXPECT_EQ(local_offer, pc_->current_local_description());
3166 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3167
3168 // Set local pranswer.
3169 SessionDescriptionInterface* local_pranswer =
3170 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3171 sdp, nullptr);
3172 EXPECT_TRUE(DoSetLocalDescription(local_pranswer));
3173 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3174 EXPECT_EQ(local_pranswer, pc_->pending_local_description());
3175 EXPECT_EQ(local_offer, pc_->current_local_description());
3176 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3177
3178 // Set local answer.
3179 SessionDescriptionInterface* local_answer = webrtc::CreateSessionDescription(
3180 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3181 EXPECT_TRUE(DoSetLocalDescription(local_answer));
3182 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3183 EXPECT_EQ(nullptr, pc_->pending_local_description());
3184 EXPECT_EQ(remote_offer, pc_->current_remote_description());
3185 EXPECT_EQ(local_answer, pc_->current_local_description());
3186}
3187
zhihuang77985012017-02-07 15:45:16 -08003188// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3189// after the PeerConnection is closed.
3190TEST_F(PeerConnectionInterfaceTest,
3191 StartAndStopLoggingAfterPeerConnectionClosed) {
3192 CreatePeerConnection();
3193 // The RtcEventLog will be reset when the PeerConnection is closed.
3194 pc_->Close();
3195
3196 rtc::PlatformFile file = 0;
3197 int64_t max_size_bytes = 1024;
3198 EXPECT_FALSE(pc_->StartRtcEventLog(file, max_size_bytes));
3199 pc_->StopRtcEventLog();
3200}
3201
deadbeef30952b42017-04-21 02:41:29 -07003202// Test that generated offers/answers include "ice-option:trickle".
3203TEST_F(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
3204 CreatePeerConnection();
3205
3206 // First, create an offer with audio/video.
3207 FakeConstraints constraints;
3208 constraints.SetMandatoryReceiveAudio(true);
3209 constraints.SetMandatoryReceiveVideo(true);
3210 std::unique_ptr<SessionDescriptionInterface> offer;
3211 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3212 cricket::SessionDescription* desc = offer->description();
3213 ASSERT_EQ(2u, desc->transport_infos().size());
3214 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3215 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3216
3217 // Apply the offer as a remote description, then create an answer.
3218 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3219 std::unique_ptr<SessionDescriptionInterface> answer;
3220 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3221 desc = answer->description();
3222 ASSERT_EQ(2u, desc->transport_infos().size());
3223 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3224 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3225}
3226
deadbeef1dcb1642017-03-29 21:08:16 -07003227// Test that ICE renomination isn't offered if it's not enabled in the PC's
3228// RTCConfiguration.
3229TEST_F(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
3230 PeerConnectionInterface::RTCConfiguration config;
3231 config.enable_ice_renomination = false;
3232 CreatePeerConnection(config, nullptr);
3233 AddVoiceStream("foo");
3234
3235 std::unique_ptr<SessionDescriptionInterface> offer;
3236 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3237 cricket::SessionDescription* desc = offer->description();
3238 EXPECT_EQ(1u, desc->transport_infos().size());
3239 EXPECT_FALSE(
3240 desc->transport_infos()[0].description.GetIceParameters().renomination);
3241}
3242
3243// Test that the ICE renomination option is present in generated offers/answers
3244// if it's enabled in the PC's RTCConfiguration.
3245TEST_F(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
3246 PeerConnectionInterface::RTCConfiguration config;
3247 config.enable_ice_renomination = true;
3248 CreatePeerConnection(config, nullptr);
3249 AddVoiceStream("foo");
3250
3251 std::unique_ptr<SessionDescriptionInterface> offer;
3252 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3253 cricket::SessionDescription* desc = offer->description();
3254 EXPECT_EQ(1u, desc->transport_infos().size());
3255 EXPECT_TRUE(
3256 desc->transport_infos()[0].description.GetIceParameters().renomination);
3257
3258 // Set the offer as a remote description, then create an answer and ensure it
3259 // has the renomination flag too.
3260 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3261 std::unique_ptr<SessionDescriptionInterface> answer;
3262 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3263 desc = answer->description();
3264 EXPECT_EQ(1u, desc->transport_infos().size());
3265 EXPECT_TRUE(
3266 desc->transport_infos()[0].description.GetIceParameters().renomination);
3267}
3268
3269// Test that if CreateOffer is called with the deprecated "offer to receive
3270// audio/video" constraints, they're processed and result in an offer with
3271// audio/video sections just as if RTCOfferAnswerOptions had been used.
3272TEST_F(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
3273 CreatePeerConnection();
3274
3275 FakeConstraints constraints;
3276 constraints.SetMandatoryReceiveAudio(true);
3277 constraints.SetMandatoryReceiveVideo(true);
3278 std::unique_ptr<SessionDescriptionInterface> offer;
3279 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3280
3281 cricket::SessionDescription* desc = offer->description();
3282 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3283 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3284 ASSERT_NE(nullptr, audio);
3285 ASSERT_NE(nullptr, video);
3286 EXPECT_FALSE(audio->rejected);
3287 EXPECT_FALSE(video->rejected);
3288}
3289
3290// Test that if CreateAnswer is called with the deprecated "offer to receive
3291// audio/video" constraints, they're processed and can be used to reject an
3292// offered m= section just as can be done with RTCOfferAnswerOptions;
3293TEST_F(PeerConnectionInterfaceTest, CreateAnswerWithOfferToReceiveConstraints) {
3294 CreatePeerConnection();
3295
3296 // First, create an offer with audio/video and apply it as a remote
3297 // description.
3298 FakeConstraints constraints;
3299 constraints.SetMandatoryReceiveAudio(true);
3300 constraints.SetMandatoryReceiveVideo(true);
3301 std::unique_ptr<SessionDescriptionInterface> offer;
3302 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3303 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3304
3305 // Now create answer that rejects audio/video.
3306 constraints.SetMandatoryReceiveAudio(false);
3307 constraints.SetMandatoryReceiveVideo(false);
3308 std::unique_ptr<SessionDescriptionInterface> answer;
3309 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3310
3311 cricket::SessionDescription* desc = answer->description();
3312 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3313 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3314 ASSERT_NE(nullptr, audio);
3315 ASSERT_NE(nullptr, video);
3316 EXPECT_TRUE(audio->rejected);
3317 EXPECT_TRUE(video->rejected);
3318}
3319
3320#ifdef HAVE_SCTP
3321#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3322 DataChannelOnlyOfferWithMaxBundlePolicy
3323#else
3324#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3325 DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy
3326#endif
3327
3328// Test that negotiation can succeed with a data channel only, and with the max
3329// bundle policy. Previously there was a bug that prevented this.
3330TEST_F(PeerConnectionInterfaceTest,
3331 MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy) {
3332 PeerConnectionInterface::RTCConfiguration config;
3333 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3334 CreatePeerConnection(config, nullptr);
3335
3336 // First, create an offer with only a data channel and apply it as a remote
3337 // description.
3338 pc_->CreateDataChannel("test", nullptr);
3339 std::unique_ptr<SessionDescriptionInterface> offer;
3340 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3341 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3342
3343 // Create and set answer as well.
3344 std::unique_ptr<SessionDescriptionInterface> answer;
3345 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3346 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
3347}
3348
zstein4b979802017-06-02 14:37:37 -07003349TEST_F(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
3350 CreatePeerConnection();
3351 PeerConnectionInterface::BitrateParameters bitrate;
3352 bitrate.current_bitrate_bps = rtc::Optional<int>(100000);
3353 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3354}
3355
3356TEST_F(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
3357 CreatePeerConnection();
3358 PeerConnectionInterface::BitrateParameters bitrate;
3359 bitrate.min_bitrate_bps = rtc::Optional<int>(-1);
3360 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3361}
3362
3363TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
3364 CreatePeerConnection();
3365 PeerConnectionInterface::BitrateParameters bitrate;
3366 bitrate.min_bitrate_bps = rtc::Optional<int>(5);
3367 bitrate.current_bitrate_bps = rtc::Optional<int>(3);
3368 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3369}
3370
3371TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
3372 CreatePeerConnection();
3373 PeerConnectionInterface::BitrateParameters bitrate;
3374 bitrate.current_bitrate_bps = rtc::Optional<int>(-1);
3375 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3376}
3377
3378TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
3379 CreatePeerConnection();
3380 PeerConnectionInterface::BitrateParameters bitrate;
3381 bitrate.current_bitrate_bps = rtc::Optional<int>(10);
3382 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3383 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3384}
3385
3386TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
3387 CreatePeerConnection();
3388 PeerConnectionInterface::BitrateParameters bitrate;
3389 bitrate.min_bitrate_bps = rtc::Optional<int>(10);
3390 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3391 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3392}
3393
3394TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
3395 CreatePeerConnection();
3396 PeerConnectionInterface::BitrateParameters bitrate;
3397 bitrate.max_bitrate_bps = rtc::Optional<int>(-1);
3398 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3399}
3400
3401// The current bitrate from Call's BitrateConfigMask is currently clamped by
3402// Call's BitrateConfig, which comes from the SDP or a default value. This test
3403// checks that a call to SetBitrate with a current bitrate that will be clamped
3404// succeeds.
3405TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
3406 CreatePeerConnection();
3407 PeerConnectionInterface::BitrateParameters bitrate;
3408 bitrate.current_bitrate_bps = rtc::Optional<int>(1);
3409 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3410}
3411
nisse51542be2016-02-12 02:27:06 -08003412class PeerConnectionMediaConfigTest : public testing::Test {
3413 protected:
3414 void SetUp() override {
zhihuang38ede132017-06-15 12:52:32 -07003415 pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
nisse51542be2016-02-12 02:27:06 -08003416 pcf_->Initialize();
3417 }
nisseeaabdf62017-05-05 02:23:02 -07003418 const cricket::MediaConfig TestCreatePeerConnection(
nisse51542be2016-02-12 02:27:06 -08003419 const PeerConnectionInterface::RTCConfiguration& config,
3420 const MediaConstraintsInterface *constraints) {
nisse51542be2016-02-12 02:27:06 -08003421
zhihuang9763d562016-08-05 11:14:50 -07003422 rtc::scoped_refptr<PeerConnectionInterface> pc(pcf_->CreatePeerConnection(
3423 config, constraints, nullptr, nullptr, &observer_));
nisse51542be2016-02-12 02:27:06 -08003424 EXPECT_TRUE(pc.get());
nisseeaabdf62017-05-05 02:23:02 -07003425 return pc->GetConfiguration().media_config;
nisse51542be2016-02-12 02:27:06 -08003426 }
3427
zhihuang9763d562016-08-05 11:14:50 -07003428 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
nisse51542be2016-02-12 02:27:06 -08003429 MockPeerConnectionObserver observer_;
3430};
3431
3432// This test verifies the default behaviour with no constraints and a
3433// default RTCConfiguration.
3434TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3435 PeerConnectionInterface::RTCConfiguration config;
3436 FakeConstraints constraints;
3437
3438 const cricket::MediaConfig& media_config =
3439 TestCreatePeerConnection(config, &constraints);
3440
3441 EXPECT_FALSE(media_config.enable_dscp);
nisse0db023a2016-03-01 04:29:59 -08003442 EXPECT_TRUE(media_config.video.enable_cpu_overuse_detection);
3443 EXPECT_FALSE(media_config.video.disable_prerenderer_smoothing);
3444 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003445}
3446
3447// This test verifies the DSCP constraint is recognized and passed to
nisse528b7932017-05-08 03:21:43 -07003448// the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003449TEST_F(PeerConnectionMediaConfigTest, TestDscpConstraintTrue) {
3450 PeerConnectionInterface::RTCConfiguration config;
3451 FakeConstraints constraints;
3452
3453 constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDscp, true);
3454 const cricket::MediaConfig& media_config =
3455 TestCreatePeerConnection(config, &constraints);
3456
3457 EXPECT_TRUE(media_config.enable_dscp);
3458}
3459
3460// This test verifies the cpu overuse detection constraint is
nisse528b7932017-05-08 03:21:43 -07003461// recognized and passed to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003462TEST_F(PeerConnectionMediaConfigTest, TestCpuOveruseConstraintFalse) {
3463 PeerConnectionInterface::RTCConfiguration config;
3464 FakeConstraints constraints;
3465
3466 constraints.AddOptional(
3467 webrtc::MediaConstraintsInterface::kCpuOveruseDetection, false);
3468 const cricket::MediaConfig media_config =
3469 TestCreatePeerConnection(config, &constraints);
3470
nisse0db023a2016-03-01 04:29:59 -08003471 EXPECT_FALSE(media_config.video.enable_cpu_overuse_detection);
nisse51542be2016-02-12 02:27:06 -08003472}
3473
3474// This test verifies that the disable_prerenderer_smoothing flag is
nisse528b7932017-05-08 03:21:43 -07003475// propagated from RTCConfiguration to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003476TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3477 PeerConnectionInterface::RTCConfiguration config;
3478 FakeConstraints constraints;
3479
Niels Möller71bdda02016-03-31 12:59:59 +02003480 config.set_prerenderer_smoothing(false);
nisse51542be2016-02-12 02:27:06 -08003481 const cricket::MediaConfig& media_config =
3482 TestCreatePeerConnection(config, &constraints);
3483
nisse0db023a2016-03-01 04:29:59 -08003484 EXPECT_TRUE(media_config.video.disable_prerenderer_smoothing);
3485}
3486
3487// This test verifies the suspend below min bitrate constraint is
nisse528b7932017-05-08 03:21:43 -07003488// recognized and passed to the PeerConnection.
nisse0db023a2016-03-01 04:29:59 -08003489TEST_F(PeerConnectionMediaConfigTest,
3490 TestSuspendBelowMinBitrateConstraintTrue) {
3491 PeerConnectionInterface::RTCConfiguration config;
3492 FakeConstraints constraints;
3493
3494 constraints.AddOptional(
3495 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3496 true);
3497 const cricket::MediaConfig media_config =
3498 TestCreatePeerConnection(config, &constraints);
3499
3500 EXPECT_TRUE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003501}
3502
deadbeefab9b2d12015-10-14 11:33:11 -07003503// The following tests verify that session options are created correctly.
deadbeefc80741f2015-10-22 13:14:45 -07003504// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of
3505// "verify options are converted correctly", should be "pass options into
3506// CreateOffer and verify the correct offer is produced."
deadbeefab9b2d12015-10-14 11:33:11 -07003507
3508TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) {
3509 RTCOfferAnswerOptions rtc_options;
3510 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3511
3512 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003513 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003514
3515 rtc_options.offer_to_receive_audio =
3516 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003517 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003518}
3519
3520TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) {
3521 RTCOfferAnswerOptions rtc_options;
3522 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3523
3524 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003525 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003526
3527 rtc_options.offer_to_receive_video =
3528 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003529 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003530}
3531
3532// Test that a MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003533// OfferToReceiveAudio and OfferToReceiveVideo options are set.
deadbeefab9b2d12015-10-14 11:33:11 -07003534TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) {
3535 RTCOfferAnswerOptions rtc_options;
3536 rtc_options.offer_to_receive_audio = 1;
3537 rtc_options.offer_to_receive_video = 1;
3538
3539 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003540 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003541 EXPECT_TRUE(options.has_audio());
3542 EXPECT_TRUE(options.has_video());
3543 EXPECT_TRUE(options.bundle_enabled);
3544}
3545
3546// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003547// OfferToReceiveAudio is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003548TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) {
3549 RTCOfferAnswerOptions rtc_options;
3550 rtc_options.offer_to_receive_audio = 1;
3551
3552 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003553 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003554 EXPECT_TRUE(options.has_audio());
3555 EXPECT_FALSE(options.has_video());
3556 EXPECT_TRUE(options.bundle_enabled);
3557}
3558
3559// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003560// the default OfferOptions are used.
deadbeefab9b2d12015-10-14 11:33:11 -07003561TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) {
3562 RTCOfferAnswerOptions rtc_options;
3563
3564 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003565 options.transport_options["audio"] = cricket::TransportOptions();
3566 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003567 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefc80741f2015-10-22 13:14:45 -07003568 EXPECT_TRUE(options.has_audio());
deadbeefab9b2d12015-10-14 11:33:11 -07003569 EXPECT_FALSE(options.has_video());
deadbeefc80741f2015-10-22 13:14:45 -07003570 EXPECT_TRUE(options.bundle_enabled);
deadbeefab9b2d12015-10-14 11:33:11 -07003571 EXPECT_TRUE(options.vad_enabled);
deadbeef0ed85b22016-02-23 17:24:52 -08003572 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3573 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003574}
3575
3576// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003577// OfferToReceiveVideo is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003578TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) {
3579 RTCOfferAnswerOptions rtc_options;
3580 rtc_options.offer_to_receive_audio = 0;
3581 rtc_options.offer_to_receive_video = 1;
3582
3583 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003584 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003585 EXPECT_FALSE(options.has_audio());
3586 EXPECT_TRUE(options.has_video());
3587 EXPECT_TRUE(options.bundle_enabled);
3588}
3589
3590// Test that a correct MediaSessionOptions is created for an offer if
3591// UseRtpMux is set to false.
3592TEST(CreateSessionOptionsTest,
3593 GetMediaSessionOptionsForOfferWithBundleDisabled) {
3594 RTCOfferAnswerOptions rtc_options;
3595 rtc_options.offer_to_receive_audio = 1;
3596 rtc_options.offer_to_receive_video = 1;
3597 rtc_options.use_rtp_mux = false;
3598
3599 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003600 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003601 EXPECT_TRUE(options.has_audio());
3602 EXPECT_TRUE(options.has_video());
3603 EXPECT_FALSE(options.bundle_enabled);
3604}
3605
3606// Test that a correct MediaSessionOptions is created to restart ice if
3607// IceRestart is set. It also tests that subsequent MediaSessionOptions don't
Taylor Brandstetterf475d362016-01-08 15:35:57 -08003608// have |audio_transport_options.ice_restart| etc. set.
deadbeefab9b2d12015-10-14 11:33:11 -07003609TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) {
3610 RTCOfferAnswerOptions rtc_options;
3611 rtc_options.ice_restart = true;
3612
3613 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003614 options.transport_options["audio"] = cricket::TransportOptions();
3615 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003616 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003617 EXPECT_TRUE(options.transport_options["audio"].ice_restart);
3618 EXPECT_TRUE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003619
3620 rtc_options = RTCOfferAnswerOptions();
htaaac2dea2016-03-10 13:35:55 -08003621 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003622 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3623 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003624}
3625
3626// Test that the MediaConstraints in an answer don't affect if audio and video
3627// is offered in an offer but that if kOfferToReceiveAudio or
3628// kOfferToReceiveVideo constraints are true in an offer, the media type will be
3629// included in subsequent answers.
3630TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) {
3631 FakeConstraints answer_c;
3632 answer_c.SetMandatoryReceiveAudio(true);
3633 answer_c.SetMandatoryReceiveVideo(true);
3634
3635 cricket::MediaSessionOptions answer_options;
3636 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options));
3637 EXPECT_TRUE(answer_options.has_audio());
3638 EXPECT_TRUE(answer_options.has_video());
3639
deadbeefc80741f2015-10-22 13:14:45 -07003640 RTCOfferAnswerOptions rtc_offer_options;
deadbeefab9b2d12015-10-14 11:33:11 -07003641
3642 cricket::MediaSessionOptions offer_options;
htaaac2dea2016-03-10 13:35:55 -08003643 EXPECT_TRUE(
3644 ExtractMediaSessionOptions(rtc_offer_options, false, &offer_options));
deadbeefc80741f2015-10-22 13:14:45 -07003645 EXPECT_TRUE(offer_options.has_audio());
htaaac2dea2016-03-10 13:35:55 -08003646 EXPECT_TRUE(offer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003647
deadbeefc80741f2015-10-22 13:14:45 -07003648 RTCOfferAnswerOptions updated_rtc_offer_options;
3649 updated_rtc_offer_options.offer_to_receive_audio = 1;
3650 updated_rtc_offer_options.offer_to_receive_video = 1;
deadbeefab9b2d12015-10-14 11:33:11 -07003651
3652 cricket::MediaSessionOptions updated_offer_options;
htaaac2dea2016-03-10 13:35:55 -08003653 EXPECT_TRUE(ExtractMediaSessionOptions(updated_rtc_offer_options, false,
htaa2a49d92016-03-04 02:51:39 -08003654 &updated_offer_options));
deadbeefab9b2d12015-10-14 11:33:11 -07003655 EXPECT_TRUE(updated_offer_options.has_audio());
3656 EXPECT_TRUE(updated_offer_options.has_video());
3657
3658 // Since an offer has been created with both audio and video, subsequent
3659 // offers and answers should contain both audio and video.
3660 // Answers will only contain the media types that exist in the offer
3661 // regardless of the value of |updated_answer_options.has_audio| and
3662 // |updated_answer_options.has_video|.
3663 FakeConstraints updated_answer_c;
3664 answer_c.SetMandatoryReceiveAudio(false);
3665 answer_c.SetMandatoryReceiveVideo(false);
3666
3667 cricket::MediaSessionOptions updated_answer_options;
3668 EXPECT_TRUE(
3669 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options));
3670 EXPECT_TRUE(updated_answer_options.has_audio());
3671 EXPECT_TRUE(updated_answer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003672}
deadbeef3edec7c2016-12-10 11:44:26 -08003673
deadbeef293e9262017-01-11 12:28:30 -08003674// Tests a few random fields being different.
3675TEST(RTCConfigurationTest, ComparisonOperators) {
3676 PeerConnectionInterface::RTCConfiguration a;
3677 PeerConnectionInterface::RTCConfiguration b;
3678 EXPECT_EQ(a, b);
3679
3680 PeerConnectionInterface::RTCConfiguration c;
3681 c.servers.push_back(PeerConnectionInterface::IceServer());
3682 EXPECT_NE(a, c);
3683
3684 PeerConnectionInterface::RTCConfiguration d;
3685 d.type = PeerConnectionInterface::kRelay;
3686 EXPECT_NE(a, d);
3687
3688 PeerConnectionInterface::RTCConfiguration e;
3689 e.audio_jitter_buffer_max_packets = 5;
3690 EXPECT_NE(a, e);
3691
3692 PeerConnectionInterface::RTCConfiguration f;
3693 f.ice_connection_receiving_timeout = 1337;
3694 EXPECT_NE(a, f);
3695
3696 PeerConnectionInterface::RTCConfiguration g;
3697 g.disable_ipv6 = true;
3698 EXPECT_NE(a, g);
3699
3700 PeerConnectionInterface::RTCConfiguration h(
3701 PeerConnectionInterface::RTCConfigurationType::kAggressive);
3702 EXPECT_NE(a, h);
3703}