Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: talk/app/webrtc/mediastreamsignaling_unittest.cc

Issue 1403633005: Revert of Moving MediaStreamSignaling logic into PeerConnection. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/app/webrtc/mediastreamsignaling.cc ('k') | talk/app/webrtc/peerconnection.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2012 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <string>
29 #include <vector>
30
31 #include "talk/app/webrtc/audiotrack.h"
32 #include "talk/app/webrtc/mediastream.h"
33 #include "talk/app/webrtc/mediastreamsignaling.h"
34 #include "talk/app/webrtc/sctputils.h"
35 #include "talk/app/webrtc/streamcollection.h"
36 #include "talk/app/webrtc/test/fakeconstraints.h"
37 #include "talk/app/webrtc/test/fakedatachannelprovider.h"
38 #include "talk/app/webrtc/videotrack.h"
39 #include "talk/media/base/fakemediaengine.h"
40 #include "webrtc/p2p/base/constants.h"
41 #include "webrtc/p2p/base/sessiondescription.h"
42 #include "talk/session/media/channelmanager.h"
43 #include "webrtc/base/gunit.h"
44 #include "webrtc/base/scoped_ptr.h"
45 #include "webrtc/base/stringutils.h"
46 #include "webrtc/base/thread.h"
47
48 static const char kStreams[][8] = {"stream1", "stream2"};
49 static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
50 static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
51
52 using webrtc::AudioTrack;
53 using webrtc::AudioTrackInterface;
54 using webrtc::AudioTrackVector;
55 using webrtc::VideoTrack;
56 using webrtc::VideoTrackInterface;
57 using webrtc::VideoTrackVector;
58 using webrtc::DataChannelInterface;
59 using webrtc::FakeConstraints;
60 using webrtc::IceCandidateInterface;
61 using webrtc::MediaConstraintsInterface;
62 using webrtc::MediaStreamInterface;
63 using webrtc::MediaStreamTrackInterface;
64 using webrtc::PeerConnectionInterface;
65 using webrtc::SdpParseError;
66 using webrtc::SessionDescriptionInterface;
67 using webrtc::StreamCollection;
68 using webrtc::StreamCollectionInterface;
69
70 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
71
72 // Reference SDP with a MediaStream with label "stream1" and audio track with
73 // id "audio_1" and a video track with id "video_1;
74 static 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"
79 "m=audio 1 RTP/AVPF 103\r\n"
80 "a=mid:audio\r\n"
81 "a=rtpmap:103 ISAC/16000\r\n"
82 "a=ssrc:1 cname:stream1\r\n"
83 "a=ssrc:1 mslabel:stream1\r\n"
84 "a=ssrc:1 label:audiotrack0\r\n"
85 "m=video 1 RTP/AVPF 120\r\n"
86 "a=mid:video\r\n"
87 "a=rtpmap:120 VP8/90000\r\n"
88 "a=ssrc:2 cname:stream1\r\n"
89 "a=ssrc:2 mslabel:stream1\r\n"
90 "a=ssrc:2 label:videotrack0\r\n";
91
92 // Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
93 // MediaStreams have one audio track and one video track.
94 // This uses MSID.
95 static const char kSdpStringWith2Stream[] =
96 "v=0\r\n"
97 "o=- 0 0 IN IP4 127.0.0.1\r\n"
98 "s=-\r\n"
99 "t=0 0\r\n"
100 "a=msid-semantic: WMS stream1 stream2\r\n"
101 "m=audio 1 RTP/AVPF 103\r\n"
102 "a=mid:audio\r\n"
103 "a=rtpmap:103 ISAC/16000\r\n"
104 "a=ssrc:1 cname:stream1\r\n"
105 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
106 "a=ssrc:3 cname:stream2\r\n"
107 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
108 "m=video 1 RTP/AVPF 120\r\n"
109 "a=mid:video\r\n"
110 "a=rtpmap:120 VP8/0\r\n"
111 "a=ssrc:2 cname:stream1\r\n"
112 "a=ssrc:2 msid:stream1 videotrack0\r\n"
113 "a=ssrc:4 cname:stream2\r\n"
114 "a=ssrc:4 msid:stream2 videotrack1\r\n";
115
116 // Reference SDP without MediaStreams. Msid is not supported.
117 static const char kSdpStringWithoutStreams[] =
118 "v=0\r\n"
119 "o=- 0 0 IN IP4 127.0.0.1\r\n"
120 "s=-\r\n"
121 "t=0 0\r\n"
122 "m=audio 1 RTP/AVPF 103\r\n"
123 "a=mid:audio\r\n"
124 "a=rtpmap:103 ISAC/16000\r\n"
125 "m=video 1 RTP/AVPF 120\r\n"
126 "a=mid:video\r\n"
127 "a=rtpmap:120 VP8/90000\r\n";
128
129 // Reference SDP without MediaStreams. Msid is supported.
130 static const char kSdpStringWithMsidWithoutStreams[] =
131 "v=0\r\n"
132 "o=- 0 0 IN IP4 127.0.0.1\r\n"
133 "s=-\r\n"
134 "t=0 0\r\n"
135 "a=msid-semantic: WMS\r\n"
136 "m=audio 1 RTP/AVPF 103\r\n"
137 "a=mid:audio\r\n"
138 "a=rtpmap:103 ISAC/16000\r\n"
139 "m=video 1 RTP/AVPF 120\r\n"
140 "a=mid:video\r\n"
141 "a=rtpmap:120 VP8/90000\r\n";
142
143 // Reference SDP without MediaStreams and audio only.
144 static const char kSdpStringWithoutStreamsAudioOnly[] =
145 "v=0\r\n"
146 "o=- 0 0 IN IP4 127.0.0.1\r\n"
147 "s=-\r\n"
148 "t=0 0\r\n"
149 "m=audio 1 RTP/AVPF 103\r\n"
150 "a=mid:audio\r\n"
151 "a=rtpmap:103 ISAC/16000\r\n";
152
153 // Reference SENDONLY SDP without MediaStreams. Msid is not supported.
154 static const char kSdpStringSendOnlyWithWithoutStreams[] =
155 "v=0\r\n"
156 "o=- 0 0 IN IP4 127.0.0.1\r\n"
157 "s=-\r\n"
158 "t=0 0\r\n"
159 "m=audio 1 RTP/AVPF 103\r\n"
160 "a=mid:audio\r\n"
161 "a=sendonly"
162 "a=rtpmap:103 ISAC/16000\r\n"
163 "m=video 1 RTP/AVPF 120\r\n"
164 "a=mid:video\r\n"
165 "a=sendonly"
166 "a=rtpmap:120 VP8/90000\r\n";
167
168 static const char kSdpStringInit[] =
169 "v=0\r\n"
170 "o=- 0 0 IN IP4 127.0.0.1\r\n"
171 "s=-\r\n"
172 "t=0 0\r\n"
173 "a=msid-semantic: WMS\r\n";
174
175 static const char kSdpStringAudio[] =
176 "m=audio 1 RTP/AVPF 103\r\n"
177 "a=mid:audio\r\n"
178 "a=rtpmap:103 ISAC/16000\r\n";
179
180 static const char kSdpStringVideo[] =
181 "m=video 1 RTP/AVPF 120\r\n"
182 "a=mid:video\r\n"
183 "a=rtpmap:120 VP8/90000\r\n";
184
185 static const char kSdpStringMs1Audio0[] =
186 "a=ssrc:1 cname:stream1\r\n"
187 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
188
189 static const char kSdpStringMs1Video0[] =
190 "a=ssrc:2 cname:stream1\r\n"
191 "a=ssrc:2 msid:stream1 videotrack0\r\n";
192
193 static const char kSdpStringMs1Audio1[] =
194 "a=ssrc:3 cname:stream1\r\n"
195 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
196
197 static const char kSdpStringMs1Video1[] =
198 "a=ssrc:4 cname:stream1\r\n"
199 "a=ssrc:4 msid:stream1 videotrack1\r\n";
200
201 // Verifies that |options| contain all tracks in |collection| and that
202 // the |options| has set the the has_audio and has_video flags correct.
203 static void VerifyMediaOptions(StreamCollectionInterface* collection,
204 const cricket::MediaSessionOptions& options) {
205 if (!collection) {
206 return;
207 }
208
209 size_t stream_index = 0;
210 for (size_t i = 0; i < collection->count(); ++i) {
211 MediaStreamInterface* stream = collection->at(i);
212 AudioTrackVector audio_tracks = stream->GetAudioTracks();
213 ASSERT_GE(options.streams.size(), stream_index + audio_tracks.size());
214 for (size_t j = 0; j < audio_tracks.size(); ++j) {
215 webrtc::AudioTrackInterface* audio = audio_tracks[j];
216 EXPECT_EQ(options.streams[stream_index].sync_label, stream->label());
217 EXPECT_EQ(options.streams[stream_index++].id, audio->id());
218 EXPECT_TRUE(options.has_audio());
219 }
220 VideoTrackVector video_tracks = stream->GetVideoTracks();
221 ASSERT_GE(options.streams.size(), stream_index + video_tracks.size());
222 for (size_t j = 0; j < video_tracks.size(); ++j) {
223 webrtc::VideoTrackInterface* video = video_tracks[j];
224 EXPECT_EQ(options.streams[stream_index].sync_label, stream->label());
225 EXPECT_EQ(options.streams[stream_index++].id, video->id());
226 EXPECT_TRUE(options.has_video());
227 }
228 }
229 }
230
231 static bool CompareStreamCollections(StreamCollectionInterface* s1,
232 StreamCollectionInterface* s2) {
233 if (s1 == NULL || s2 == NULL || s1->count() != s2->count())
234 return false;
235
236 for (size_t i = 0; i != s1->count(); ++i) {
237 if (s1->at(i)->label() != s2->at(i)->label())
238 return false;
239 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
240 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
241 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
242 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
243
244 if (audio_tracks1.size() != audio_tracks2.size())
245 return false;
246 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
247 if (audio_tracks1[j]->id() != audio_tracks2[j]->id())
248 return false;
249 }
250 if (video_tracks1.size() != video_tracks2.size())
251 return false;
252 for (size_t j = 0; j != video_tracks1.size(); ++j) {
253 if (video_tracks1[j]->id() != video_tracks2[j]->id())
254 return false;
255 }
256 }
257 return true;
258 }
259
260 class FakeDataChannelFactory : public webrtc::DataChannelFactory {
261 public:
262 FakeDataChannelFactory(FakeDataChannelProvider* provider,
263 cricket::DataChannelType dct,
264 webrtc::MediaStreamSignaling* media_stream_signaling)
265 : provider_(provider),
266 type_(dct),
267 media_stream_signaling_(media_stream_signaling) {}
268
269 virtual rtc::scoped_refptr<webrtc::DataChannel> CreateDataChannel(
270 const std::string& label,
271 const webrtc::InternalDataChannelInit* config) {
272 last_init_ = *config;
273 rtc::scoped_refptr<webrtc::DataChannel> data_channel =
274 webrtc::DataChannel::Create(provider_, type_, label, *config);
275 media_stream_signaling_->AddDataChannel(data_channel);
276 return data_channel;
277 }
278
279 const webrtc::InternalDataChannelInit& last_init() const {
280 return last_init_;
281 }
282
283 private:
284 FakeDataChannelProvider* provider_;
285 cricket::DataChannelType type_;
286 webrtc::MediaStreamSignaling* media_stream_signaling_;
287 webrtc::InternalDataChannelInit last_init_;
288 };
289
290 class MockSignalingObserver : public webrtc::MediaStreamSignalingObserver {
291 public:
292 MockSignalingObserver()
293 : remote_media_streams_(StreamCollection::Create()) {
294 }
295
296 virtual ~MockSignalingObserver() {
297 }
298
299 // New remote stream have been discovered.
300 virtual void OnAddRemoteStream(MediaStreamInterface* remote_stream) {
301 remote_media_streams_->AddStream(remote_stream);
302 }
303
304 // Remote stream is no longer available.
305 virtual void OnRemoveRemoteStream(MediaStreamInterface* remote_stream) {
306 remote_media_streams_->RemoveStream(remote_stream);
307 }
308
309 virtual void OnAddDataChannel(DataChannelInterface* data_channel) {
310 }
311
312 virtual void OnAddLocalAudioTrack(MediaStreamInterface* stream,
313 AudioTrackInterface* audio_track,
314 uint32_t ssrc) {
315 AddTrack(&local_audio_tracks_, stream, audio_track, ssrc);
316 }
317
318 virtual void OnAddLocalVideoTrack(MediaStreamInterface* stream,
319 VideoTrackInterface* video_track,
320 uint32_t ssrc) {
321 AddTrack(&local_video_tracks_, stream, video_track, ssrc);
322 }
323
324 virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
325 AudioTrackInterface* audio_track,
326 uint32_t ssrc) {
327 RemoveTrack(&local_audio_tracks_, stream, audio_track);
328 }
329
330 virtual void OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
331 VideoTrackInterface* video_track) {
332 RemoveTrack(&local_video_tracks_, stream, video_track);
333 }
334
335 virtual void OnAddRemoteAudioTrack(MediaStreamInterface* stream,
336 AudioTrackInterface* audio_track,
337 uint32_t ssrc) {
338 AddTrack(&remote_audio_tracks_, stream, audio_track, ssrc);
339 }
340
341 virtual void OnAddRemoteVideoTrack(MediaStreamInterface* stream,
342 VideoTrackInterface* video_track,
343 uint32_t ssrc) {
344 AddTrack(&remote_video_tracks_, stream, video_track, ssrc);
345 }
346
347 virtual void OnRemoveRemoteAudioTrack(MediaStreamInterface* stream,
348 AudioTrackInterface* audio_track) {
349 RemoveTrack(&remote_audio_tracks_, stream, audio_track);
350 }
351
352 virtual void OnRemoveRemoteVideoTrack(MediaStreamInterface* stream,
353 VideoTrackInterface* video_track) {
354 RemoveTrack(&remote_video_tracks_, stream, video_track);
355 }
356
357 virtual void OnRemoveLocalStream(MediaStreamInterface* stream) {
358 }
359
360 MediaStreamInterface* RemoteStream(const std::string& label) {
361 return remote_media_streams_->find(label);
362 }
363
364 StreamCollectionInterface* remote_streams() const {
365 return remote_media_streams_;
366 }
367
368 size_t NumberOfRemoteAudioTracks() { return remote_audio_tracks_.size(); }
369
370 void VerifyRemoteAudioTrack(const std::string& stream_label,
371 const std::string& track_id,
372 uint32_t ssrc) {
373 VerifyTrack(remote_audio_tracks_, stream_label, track_id, ssrc);
374 }
375
376 size_t NumberOfRemoteVideoTracks() { return remote_video_tracks_.size(); }
377
378 void VerifyRemoteVideoTrack(const std::string& stream_label,
379 const std::string& track_id,
380 uint32_t ssrc) {
381 VerifyTrack(remote_video_tracks_, stream_label, track_id, ssrc);
382 }
383
384 size_t NumberOfLocalAudioTracks() { return local_audio_tracks_.size(); }
385 void VerifyLocalAudioTrack(const std::string& stream_label,
386 const std::string& track_id,
387 uint32_t ssrc) {
388 VerifyTrack(local_audio_tracks_, stream_label, track_id, ssrc);
389 }
390
391 size_t NumberOfLocalVideoTracks() { return local_video_tracks_.size(); }
392
393 void VerifyLocalVideoTrack(const std::string& stream_label,
394 const std::string& track_id,
395 uint32_t ssrc) {
396 VerifyTrack(local_video_tracks_, stream_label, track_id, ssrc);
397 }
398
399 private:
400 struct TrackInfo {
401 TrackInfo() {}
402 TrackInfo(const std::string& stream_label,
403 const std::string track_id,
404 uint32_t ssrc)
405 : stream_label(stream_label), track_id(track_id), ssrc(ssrc) {}
406 std::string stream_label;
407 std::string track_id;
408 uint32_t ssrc;
409 };
410 typedef std::vector<TrackInfo> TrackInfos;
411
412 void AddTrack(TrackInfos* track_infos,
413 MediaStreamInterface* stream,
414 MediaStreamTrackInterface* track,
415 uint32_t ssrc) {
416 (*track_infos).push_back(TrackInfo(stream->label(), track->id(), ssrc));
417 }
418
419 void RemoveTrack(TrackInfos* track_infos, MediaStreamInterface* stream,
420 MediaStreamTrackInterface* track) {
421 for (TrackInfos::iterator it = track_infos->begin();
422 it != track_infos->end(); ++it) {
423 if (it->stream_label == stream->label() && it->track_id == track->id()) {
424 track_infos->erase(it);
425 return;
426 }
427 }
428 ADD_FAILURE();
429 }
430
431 const TrackInfo* FindTrackInfo(const TrackInfos& infos,
432 const std::string& stream_label,
433 const std::string track_id) const {
434 for (TrackInfos::const_iterator it = infos.begin();
435 it != infos.end(); ++it) {
436 if (it->stream_label == stream_label && it->track_id == track_id)
437 return &*it;
438 }
439 return NULL;
440 }
441
442 void VerifyTrack(const TrackInfos& track_infos,
443 const std::string& stream_label,
444 const std::string& track_id,
445 uint32_t ssrc) {
446 const TrackInfo* track_info = FindTrackInfo(track_infos,
447 stream_label,
448 track_id);
449 ASSERT_TRUE(track_info != NULL);
450 EXPECT_EQ(ssrc, track_info->ssrc);
451 }
452
453 TrackInfos remote_audio_tracks_;
454 TrackInfos remote_video_tracks_;
455 TrackInfos local_audio_tracks_;
456 TrackInfos local_video_tracks_;
457
458 rtc::scoped_refptr<StreamCollection> remote_media_streams_;
459 };
460
461 class MediaStreamSignalingForTest : public webrtc::MediaStreamSignaling {
462 public:
463 MediaStreamSignalingForTest(MockSignalingObserver* observer,
464 cricket::ChannelManager* channel_manager)
465 : webrtc::MediaStreamSignaling(rtc::Thread::Current(), observer,
466 channel_manager) {
467 };
468
469 using webrtc::MediaStreamSignaling::GetOptionsForOffer;
470 using webrtc::MediaStreamSignaling::GetOptionsForAnswer;
471 using webrtc::MediaStreamSignaling::OnRemoteDescriptionChanged;
472 using webrtc::MediaStreamSignaling::remote_streams;
473 };
474
475 class MediaStreamSignalingTest: public testing::Test {
476 protected:
477 virtual void SetUp() {
478 observer_.reset(new MockSignalingObserver());
479 channel_manager_.reset(
480 new cricket::ChannelManager(new cricket::FakeMediaEngine(),
481 rtc::Thread::Current()));
482 signaling_.reset(new MediaStreamSignalingForTest(observer_.get(),
483 channel_manager_.get()));
484 data_channel_provider_.reset(new FakeDataChannelProvider());
485 }
486
487 // Create a collection of streams.
488 // CreateStreamCollection(1) creates a collection that
489 // correspond to kSdpString1.
490 // CreateStreamCollection(2) correspond to kSdpString2.
491 rtc::scoped_refptr<StreamCollection>
492 CreateStreamCollection(int number_of_streams) {
493 rtc::scoped_refptr<StreamCollection> local_collection(
494 StreamCollection::Create());
495
496 for (int i = 0; i < number_of_streams; ++i) {
497 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
498 webrtc::MediaStream::Create(kStreams[i]));
499
500 // Add a local audio track.
501 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
502 webrtc::AudioTrack::Create(kAudioTracks[i], NULL));
503 stream->AddTrack(audio_track);
504
505 // Add a local video track.
506 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
507 webrtc::VideoTrack::Create(kVideoTracks[i], NULL));
508 stream->AddTrack(video_track);
509
510 local_collection->AddStream(stream);
511 }
512 return local_collection;
513 }
514
515 // This functions Creates a MediaStream with label kStreams[0] and
516 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
517 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
518 // is returned in |desc| and the MediaStream is stored in
519 // |reference_collection_|
520 void CreateSessionDescriptionAndReference(
521 size_t number_of_audio_tracks,
522 size_t number_of_video_tracks,
523 SessionDescriptionInterface** desc) {
524 ASSERT_TRUE(desc != NULL);
525 ASSERT_LE(number_of_audio_tracks, 2u);
526 ASSERT_LE(number_of_video_tracks, 2u);
527
528 reference_collection_ = StreamCollection::Create();
529 std::string sdp_ms1 = std::string(kSdpStringInit);
530
531 std::string mediastream_label = kStreams[0];
532
533 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
534 webrtc::MediaStream::Create(mediastream_label));
535 reference_collection_->AddStream(stream);
536
537 if (number_of_audio_tracks > 0) {
538 sdp_ms1 += std::string(kSdpStringAudio);
539 sdp_ms1 += std::string(kSdpStringMs1Audio0);
540 AddAudioTrack(kAudioTracks[0], stream);
541 }
542 if (number_of_audio_tracks > 1) {
543 sdp_ms1 += kSdpStringMs1Audio1;
544 AddAudioTrack(kAudioTracks[1], stream);
545 }
546
547 if (number_of_video_tracks > 0) {
548 sdp_ms1 += std::string(kSdpStringVideo);
549 sdp_ms1 += std::string(kSdpStringMs1Video0);
550 AddVideoTrack(kVideoTracks[0], stream);
551 }
552 if (number_of_video_tracks > 1) {
553 sdp_ms1 += kSdpStringMs1Video1;
554 AddVideoTrack(kVideoTracks[1], stream);
555 }
556
557 *desc = webrtc::CreateSessionDescription(
558 SessionDescriptionInterface::kOffer, sdp_ms1, NULL);
559 }
560
561 void AddAudioTrack(const std::string& track_id,
562 MediaStreamInterface* stream) {
563 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
564 webrtc::AudioTrack::Create(track_id, NULL));
565 ASSERT_TRUE(stream->AddTrack(audio_track));
566 }
567
568 void AddVideoTrack(const std::string& track_id,
569 MediaStreamInterface* stream) {
570 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
571 webrtc::VideoTrack::Create(track_id, NULL));
572 ASSERT_TRUE(stream->AddTrack(video_track));
573 }
574
575 rtc::scoped_refptr<webrtc::DataChannel> AddDataChannel(
576 cricket::DataChannelType type, const std::string& label, int id) {
577 webrtc::InternalDataChannelInit config;
578 config.id = id;
579 rtc::scoped_refptr<webrtc::DataChannel> data_channel(
580 webrtc::DataChannel::Create(
581 data_channel_provider_.get(), type, label, config));
582 EXPECT_TRUE(data_channel.get() != NULL);
583 EXPECT_TRUE(signaling_->AddDataChannel(data_channel.get()));
584 return data_channel;
585 }
586
587 // ChannelManager is used by VideoSource, so it should be released after all
588 // the video tracks. Put it as the first private variable should ensure that.
589 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
590 rtc::scoped_refptr<StreamCollection> reference_collection_;
591 rtc::scoped_ptr<MockSignalingObserver> observer_;
592 rtc::scoped_ptr<MediaStreamSignalingForTest> signaling_;
593 rtc::scoped_ptr<FakeDataChannelProvider> data_channel_provider_;
594 };
595
596 TEST_F(MediaStreamSignalingTest, GetOptionsForOfferWithInvalidAudioOption) {
597 RTCOfferAnswerOptions rtc_options;
598 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
599
600 cricket::MediaSessionOptions options;
601 EXPECT_FALSE(signaling_->GetOptionsForOffer(rtc_options, &options));
602
603 rtc_options.offer_to_receive_audio =
604 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
605 EXPECT_FALSE(signaling_->GetOptionsForOffer(rtc_options, &options));
606 }
607
608
609 TEST_F(MediaStreamSignalingTest, GetOptionsForOfferWithInvalidVideoOption) {
610 RTCOfferAnswerOptions rtc_options;
611 rtc_options.offer_to_receive_video =
612 RTCOfferAnswerOptions::kUndefined - 1;
613
614 cricket::MediaSessionOptions options;
615 EXPECT_FALSE(signaling_->GetOptionsForOffer(rtc_options, &options));
616
617 rtc_options.offer_to_receive_video =
618 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
619 EXPECT_FALSE(signaling_->GetOptionsForOffer(rtc_options, &options));
620 }
621
622 // Test that a MediaSessionOptions is created for an offer if
623 // OfferToReceiveAudio and OfferToReceiveVideo options are set but no
624 // MediaStreams are sent.
625 TEST_F(MediaStreamSignalingTest, GetMediaSessionOptionsForOfferWithAudioVideo) {
626 RTCOfferAnswerOptions rtc_options;
627 rtc_options.offer_to_receive_audio = 1;
628 rtc_options.offer_to_receive_video = 1;
629
630 cricket::MediaSessionOptions options;
631 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
632 EXPECT_TRUE(options.has_audio());
633 EXPECT_TRUE(options.has_video());
634 EXPECT_TRUE(options.bundle_enabled);
635 }
636
637 // Test that a correct MediaSessionOptions is created for an offer if
638 // OfferToReceiveAudio is set but no MediaStreams are sent.
639 TEST_F(MediaStreamSignalingTest, GetMediaSessionOptionsForOfferWithAudio) {
640 RTCOfferAnswerOptions rtc_options;
641 rtc_options.offer_to_receive_audio = 1;
642
643 cricket::MediaSessionOptions options;
644 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
645 EXPECT_TRUE(options.has_audio());
646 EXPECT_FALSE(options.has_video());
647 EXPECT_TRUE(options.bundle_enabled);
648 }
649
650 // Test that a correct MediaSessionOptions is created for an offer if
651 // the default OfferOptons is used or MediaStreams are sent.
652 TEST_F(MediaStreamSignalingTest, GetDefaultMediaSessionOptionsForOffer) {
653 RTCOfferAnswerOptions rtc_options;
654
655 cricket::MediaSessionOptions options;
656 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
657 EXPECT_FALSE(options.has_audio());
658 EXPECT_FALSE(options.has_video());
659 EXPECT_FALSE(options.bundle_enabled);
660 EXPECT_TRUE(options.vad_enabled);
661 EXPECT_FALSE(options.transport_options.ice_restart);
662 }
663
664 // Test that a correct MediaSessionOptions is created for an offer if
665 // OfferToReceiveVideo is set but no MediaStreams are sent.
666 TEST_F(MediaStreamSignalingTest, GetMediaSessionOptionsForOfferWithVideo) {
667 RTCOfferAnswerOptions rtc_options;
668 rtc_options.offer_to_receive_audio = 0;
669 rtc_options.offer_to_receive_video = 1;
670
671 cricket::MediaSessionOptions options;
672 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
673 EXPECT_FALSE(options.has_audio());
674 EXPECT_TRUE(options.has_video());
675 EXPECT_TRUE(options.bundle_enabled);
676 }
677
678 // Test that a correct MediaSessionOptions is created for an offer if
679 // UseRtpMux is set to false.
680 TEST_F(MediaStreamSignalingTest,
681 GetMediaSessionOptionsForOfferWithBundleDisabled) {
682 RTCOfferAnswerOptions rtc_options;
683 rtc_options.offer_to_receive_audio = 1;
684 rtc_options.offer_to_receive_video = 1;
685 rtc_options.use_rtp_mux = false;
686
687 cricket::MediaSessionOptions options;
688 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
689 EXPECT_TRUE(options.has_audio());
690 EXPECT_TRUE(options.has_video());
691 EXPECT_FALSE(options.bundle_enabled);
692 }
693
694 // Test that a correct MediaSessionOptions is created to restart ice if
695 // IceRestart is set. It also tests that subsequent MediaSessionOptions don't
696 // have |transport_options.ice_restart| set.
697 TEST_F(MediaStreamSignalingTest,
698 GetMediaSessionOptionsForOfferWithIceRestart) {
699 RTCOfferAnswerOptions rtc_options;
700 rtc_options.ice_restart = true;
701
702 cricket::MediaSessionOptions options;
703 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
704 EXPECT_TRUE(options.transport_options.ice_restart);
705
706 rtc_options = RTCOfferAnswerOptions();
707 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
708 EXPECT_FALSE(options.transport_options.ice_restart);
709 }
710
711 // Test that a correct MediaSessionOptions are created for an offer if
712 // a MediaStream is sent and later updated with a new track.
713 // MediaConstraints are not used.
714 TEST_F(MediaStreamSignalingTest, AddTrackToLocalMediaStream) {
715 RTCOfferAnswerOptions rtc_options;
716 rtc::scoped_refptr<StreamCollection> local_streams(
717 CreateStreamCollection(1));
718 MediaStreamInterface* local_stream = local_streams->at(0);
719 EXPECT_TRUE(signaling_->AddLocalStream(local_stream));
720 cricket::MediaSessionOptions options;
721 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
722 VerifyMediaOptions(local_streams, options);
723
724 cricket::MediaSessionOptions updated_options;
725 local_stream->AddTrack(AudioTrack::Create(kAudioTracks[1], NULL));
726 EXPECT_TRUE(signaling_->GetOptionsForOffer(rtc_options, &options));
727 VerifyMediaOptions(local_streams, options);
728 }
729
730 // Test that the MediaConstraints in an answer don't affect if audio and video
731 // is offered in an offer but that if kOfferToReceiveAudio or
732 // kOfferToReceiveVideo constraints are true in an offer, the media type will be
733 // included in subsequent answers.
734 TEST_F(MediaStreamSignalingTest, MediaConstraintsInAnswer) {
735 FakeConstraints answer_c;
736 answer_c.SetMandatoryReceiveAudio(true);
737 answer_c.SetMandatoryReceiveVideo(true);
738
739 cricket::MediaSessionOptions answer_options;
740 EXPECT_TRUE(signaling_->GetOptionsForAnswer(&answer_c, &answer_options));
741 EXPECT_TRUE(answer_options.has_audio());
742 EXPECT_TRUE(answer_options.has_video());
743
744 RTCOfferAnswerOptions rtc_offer_optoins;
745
746 cricket::MediaSessionOptions offer_options;
747 EXPECT_TRUE(
748 signaling_->GetOptionsForOffer(rtc_offer_optoins, &offer_options));
749 EXPECT_FALSE(offer_options.has_audio());
750 EXPECT_FALSE(offer_options.has_video());
751
752 RTCOfferAnswerOptions updated_rtc_offer_optoins;
753 updated_rtc_offer_optoins.offer_to_receive_audio = 1;
754 updated_rtc_offer_optoins.offer_to_receive_video = 1;
755
756 cricket::MediaSessionOptions updated_offer_options;
757 EXPECT_TRUE(signaling_->GetOptionsForOffer(updated_rtc_offer_optoins,
758 &updated_offer_options));
759 EXPECT_TRUE(updated_offer_options.has_audio());
760 EXPECT_TRUE(updated_offer_options.has_video());
761
762 // Since an offer has been created with both audio and video, subsequent
763 // offers and answers should contain both audio and video.
764 // Answers will only contain the media types that exist in the offer
765 // regardless of the value of |updated_answer_options.has_audio| and
766 // |updated_answer_options.has_video|.
767 FakeConstraints updated_answer_c;
768 answer_c.SetMandatoryReceiveAudio(false);
769 answer_c.SetMandatoryReceiveVideo(false);
770
771 cricket::MediaSessionOptions updated_answer_options;
772 EXPECT_TRUE(signaling_->GetOptionsForAnswer(&updated_answer_c,
773 &updated_answer_options));
774 EXPECT_TRUE(updated_answer_options.has_audio());
775 EXPECT_TRUE(updated_answer_options.has_video());
776
777 RTCOfferAnswerOptions default_rtc_options;
778 EXPECT_TRUE(signaling_->GetOptionsForOffer(default_rtc_options,
779 &updated_offer_options));
780 // By default, |has_audio| or |has_video| are false if there is no media
781 // track.
782 EXPECT_FALSE(updated_offer_options.has_audio());
783 EXPECT_FALSE(updated_offer_options.has_video());
784 }
785
786 // This test verifies that the remote MediaStreams corresponding to a received
787 // SDP string is created. In this test the two separate MediaStreams are
788 // signaled.
789 TEST_F(MediaStreamSignalingTest, UpdateRemoteStreams) {
790 rtc::scoped_ptr<SessionDescriptionInterface> desc(
791 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
792 kSdpStringWithStream1, NULL));
793 EXPECT_TRUE(desc != NULL);
794 signaling_->OnRemoteDescriptionChanged(desc.get());
795
796 rtc::scoped_refptr<StreamCollection> reference(
797 CreateStreamCollection(1));
798 EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
799 reference.get()));
800 EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
801 reference.get()));
802 EXPECT_EQ(1u, observer_->NumberOfRemoteAudioTracks());
803 observer_->VerifyRemoteAudioTrack(kStreams[0], kAudioTracks[0], 1);
804 EXPECT_EQ(1u, observer_->NumberOfRemoteVideoTracks());
805 observer_->VerifyRemoteVideoTrack(kStreams[0], kVideoTracks[0], 2);
806 ASSERT_EQ(1u, observer_->remote_streams()->count());
807 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
808 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != NULL);
809
810 // Create a session description based on another SDP with another
811 // MediaStream.
812 rtc::scoped_ptr<SessionDescriptionInterface> update_desc(
813 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
814 kSdpStringWith2Stream, NULL));
815 EXPECT_TRUE(update_desc != NULL);
816 signaling_->OnRemoteDescriptionChanged(update_desc.get());
817
818 rtc::scoped_refptr<StreamCollection> reference2(
819 CreateStreamCollection(2));
820 EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
821 reference2.get()));
822 EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
823 reference2.get()));
824
825 EXPECT_EQ(2u, observer_->NumberOfRemoteAudioTracks());
826 observer_->VerifyRemoteAudioTrack(kStreams[0], kAudioTracks[0], 1);
827 observer_->VerifyRemoteAudioTrack(kStreams[1], kAudioTracks[1], 3);
828 EXPECT_EQ(2u, observer_->NumberOfRemoteVideoTracks());
829 observer_->VerifyRemoteVideoTrack(kStreams[0], kVideoTracks[0], 2);
830 observer_->VerifyRemoteVideoTrack(kStreams[1], kVideoTracks[1], 4);
831 }
832
833 // This test verifies that the remote MediaStreams corresponding to a received
834 // SDP string is created. In this test the same remote MediaStream is signaled
835 // but MediaStream tracks are added and removed.
836 TEST_F(MediaStreamSignalingTest, AddRemoveTrackFromExistingRemoteMediaStream) {
837 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1;
838 CreateSessionDescriptionAndReference(1, 1, desc_ms1.use());
839 signaling_->OnRemoteDescriptionChanged(desc_ms1.get());
840 EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
841 reference_collection_));
842
843 // Add extra audio and video tracks to the same MediaStream.
844 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1_two_tracks;
845 CreateSessionDescriptionAndReference(2, 2, desc_ms1_two_tracks.use());
846 signaling_->OnRemoteDescriptionChanged(desc_ms1_two_tracks.get());
847 EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
848 reference_collection_));
849 EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
850 reference_collection_));
851
852 // Remove the extra audio and video tracks again.
853 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms2;
854 CreateSessionDescriptionAndReference(1, 1, desc_ms2.use());
855 signaling_->OnRemoteDescriptionChanged(desc_ms2.get());
856 EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
857 reference_collection_));
858 EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
859 reference_collection_));
860 }
861
862 // This test that remote tracks are ended if a
863 // local session description is set that rejects the media content type.
864 TEST_F(MediaStreamSignalingTest, RejectMediaContent) {
865 rtc::scoped_ptr<SessionDescriptionInterface> desc(
866 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
867 kSdpStringWithStream1, NULL));
868 EXPECT_TRUE(desc != NULL);
869 signaling_->OnRemoteDescriptionChanged(desc.get());
870
871 ASSERT_EQ(1u, observer_->remote_streams()->count());
872 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
873 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
874 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
875
876 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video =
877 remote_stream->GetVideoTracks()[0];
878 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state());
879 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio =
880 remote_stream->GetAudioTracks()[0];
881 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
882
883 cricket::ContentInfo* video_info =
884 desc->description()->GetContentByName("video");
885 ASSERT_TRUE(video_info != NULL);
886 video_info->rejected = true;
887 signaling_->OnLocalDescriptionChanged(desc.get());
888 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state());
889 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
890
891 cricket::ContentInfo* audio_info =
892 desc->description()->GetContentByName("audio");
893 ASSERT_TRUE(audio_info != NULL);
894 audio_info->rejected = true;
895 signaling_->OnLocalDescriptionChanged(desc.get());
896 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_audio->state());
897 }
898
899 // This test that it won't crash if the remote track as been removed outside
900 // of MediaStreamSignaling and then MediaStreamSignaling tries to reject
901 // this track.
902 TEST_F(MediaStreamSignalingTest, RemoveTrackThenRejectMediaContent) {
903 rtc::scoped_ptr<SessionDescriptionInterface> desc(
904 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
905 kSdpStringWithStream1, NULL));
906 EXPECT_TRUE(desc != NULL);
907 signaling_->OnRemoteDescriptionChanged(desc.get());
908
909 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
910 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
911 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
912
913 cricket::ContentInfo* video_info =
914 desc->description()->GetContentByName("video");
915 video_info->rejected = true;
916 signaling_->OnLocalDescriptionChanged(desc.get());
917
918 cricket::ContentInfo* audio_info =
919 desc->description()->GetContentByName("audio");
920 audio_info->rejected = true;
921 signaling_->OnLocalDescriptionChanged(desc.get());
922
923 // No crash is a pass.
924 }
925
926 // This tests that a default MediaStream is created if a remote session
927 // description doesn't contain any streams and no MSID support.
928 // It also tests that the default stream is updated if a video m-line is added
929 // in a subsequent session description.
930 TEST_F(MediaStreamSignalingTest, SdpWithoutMsidCreatesDefaultStream) {
931 rtc::scoped_ptr<SessionDescriptionInterface> desc_audio_only(
932 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
933 kSdpStringWithoutStreamsAudioOnly,
934 NULL));
935 ASSERT_TRUE(desc_audio_only != NULL);
936 signaling_->OnRemoteDescriptionChanged(desc_audio_only.get());
937
938 EXPECT_EQ(1u, signaling_->remote_streams()->count());
939 ASSERT_EQ(1u, observer_->remote_streams()->count());
940 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
941
942 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
943 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
944 EXPECT_EQ("default", remote_stream->label());
945
946 rtc::scoped_ptr<SessionDescriptionInterface> desc(
947 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
948 kSdpStringWithoutStreams, NULL));
949 ASSERT_TRUE(desc != NULL);
950 signaling_->OnRemoteDescriptionChanged(desc.get());
951 EXPECT_EQ(1u, signaling_->remote_streams()->count());
952 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
953 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
954 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
955 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
956 observer_->VerifyRemoteAudioTrack("default", "defaulta0", 0);
957 observer_->VerifyRemoteVideoTrack("default", "defaultv0", 0);
958 }
959
960 // This tests that a default MediaStream is created if a remote session
961 // description doesn't contain any streams and media direction is send only.
962 TEST_F(MediaStreamSignalingTest, RecvOnlySdpWithoutMsidCreatesDefaultStream) {
963 rtc::scoped_ptr<SessionDescriptionInterface> desc(
964 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
965 kSdpStringSendOnlyWithWithoutStreams,
966 NULL));
967 ASSERT_TRUE(desc != NULL);
968 signaling_->OnRemoteDescriptionChanged(desc.get());
969
970 EXPECT_EQ(1u, signaling_->remote_streams()->count());
971 ASSERT_EQ(1u, observer_->remote_streams()->count());
972 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
973
974 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
975 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
976 EXPECT_EQ("default", remote_stream->label());
977 }
978
979 // This tests that it won't crash when MediaStreamSignaling tries to remove
980 // a remote track that as already been removed from the mediastream.
981 TEST_F(MediaStreamSignalingTest, RemoveAlreadyGoneRemoteStream) {
982 rtc::scoped_ptr<SessionDescriptionInterface> desc_audio_only(
983 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
984 kSdpStringWithoutStreams,
985 NULL));
986 ASSERT_TRUE(desc_audio_only != NULL);
987 signaling_->OnRemoteDescriptionChanged(desc_audio_only.get());
988 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
989 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
990 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
991
992 rtc::scoped_ptr<SessionDescriptionInterface> desc(
993 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
994 kSdpStringWithoutStreams, NULL));
995 ASSERT_TRUE(desc != NULL);
996 signaling_->OnRemoteDescriptionChanged(desc.get());
997
998 // No crash is a pass.
999 }
1000
1001 // This tests that a default MediaStream is created if the remote session
1002 // description doesn't contain any streams and don't contain an indication if
1003 // MSID is supported.
1004 TEST_F(MediaStreamSignalingTest,
1005 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
1006 rtc::scoped_ptr<SessionDescriptionInterface> desc(
1007 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1008 kSdpStringWithoutStreams,
1009 NULL));
1010 ASSERT_TRUE(desc != NULL);
1011 signaling_->OnRemoteDescriptionChanged(desc.get());
1012
1013 ASSERT_EQ(1u, observer_->remote_streams()->count());
1014 MediaStreamInterface* remote_stream = observer_->remote_streams()->at(0);
1015 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
1016 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
1017 }
1018
1019 // This tests that a default MediaStream is not created if the remote session
1020 // description doesn't contain any streams but does support MSID.
1021 TEST_F(MediaStreamSignalingTest, SdpWitMsidDontCreatesDefaultStream) {
1022 rtc::scoped_ptr<SessionDescriptionInterface> desc_msid_without_streams(
1023 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1024 kSdpStringWithMsidWithoutStreams,
1025 NULL));
1026 signaling_->OnRemoteDescriptionChanged(desc_msid_without_streams.get());
1027 EXPECT_EQ(0u, observer_->remote_streams()->count());
1028 }
1029
1030 // This test that a default MediaStream is not created if a remote session
1031 // description is updated to not have any MediaStreams.
1032 TEST_F(MediaStreamSignalingTest, VerifyDefaultStreamIsNotCreated) {
1033 rtc::scoped_ptr<SessionDescriptionInterface> desc(
1034 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1035 kSdpStringWithStream1,
1036 NULL));
1037 ASSERT_TRUE(desc != NULL);
1038 signaling_->OnRemoteDescriptionChanged(desc.get());
1039 rtc::scoped_refptr<StreamCollection> reference(
1040 CreateStreamCollection(1));
1041 EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
1042 reference.get()));
1043
1044 rtc::scoped_ptr<SessionDescriptionInterface> desc_without_streams(
1045 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1046 kSdpStringWithoutStreams,
1047 NULL));
1048 signaling_->OnRemoteDescriptionChanged(desc_without_streams.get());
1049 EXPECT_EQ(0u, observer_->remote_streams()->count());
1050 }
1051
1052 // This test that the correct MediaStreamSignalingObserver methods are called
1053 // when MediaStreamSignaling::OnLocalDescriptionChanged is called with an
1054 // updated local session description.
1055 TEST_F(MediaStreamSignalingTest, LocalDescriptionChanged) {
1056 rtc::scoped_ptr<SessionDescriptionInterface> desc_1;
1057 CreateSessionDescriptionAndReference(2, 2, desc_1.use());
1058
1059 signaling_->AddLocalStream(reference_collection_->at(0));
1060 signaling_->OnLocalDescriptionChanged(desc_1.get());
1061 EXPECT_EQ(2u, observer_->NumberOfLocalAudioTracks());
1062 EXPECT_EQ(2u, observer_->NumberOfLocalVideoTracks());
1063 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[0], 1);
1064 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[0], 2);
1065 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[1], 3);
1066 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[1], 4);
1067
1068 // Remove an audio and video track.
1069 rtc::scoped_ptr<SessionDescriptionInterface> desc_2;
1070 CreateSessionDescriptionAndReference(1, 1, desc_2.use());
1071 signaling_->OnLocalDescriptionChanged(desc_2.get());
1072 EXPECT_EQ(1u, observer_->NumberOfLocalAudioTracks());
1073 EXPECT_EQ(1u, observer_->NumberOfLocalVideoTracks());
1074 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[0], 1);
1075 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[0], 2);
1076 }
1077
1078 // This test that the correct MediaStreamSignalingObserver methods are called
1079 // when MediaStreamSignaling::AddLocalStream is called after
1080 // MediaStreamSignaling::OnLocalDescriptionChanged is called.
1081 TEST_F(MediaStreamSignalingTest, AddLocalStreamAfterLocalDescriptionChanged) {
1082 rtc::scoped_ptr<SessionDescriptionInterface> desc_1;
1083 CreateSessionDescriptionAndReference(2, 2, desc_1.use());
1084
1085 signaling_->OnLocalDescriptionChanged(desc_1.get());
1086 EXPECT_EQ(0u, observer_->NumberOfLocalAudioTracks());
1087 EXPECT_EQ(0u, observer_->NumberOfLocalVideoTracks());
1088
1089 signaling_->AddLocalStream(reference_collection_->at(0));
1090 EXPECT_EQ(2u, observer_->NumberOfLocalAudioTracks());
1091 EXPECT_EQ(2u, observer_->NumberOfLocalVideoTracks());
1092 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[0], 1);
1093 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[0], 2);
1094 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[1], 3);
1095 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[1], 4);
1096 }
1097
1098 // This test that the correct MediaStreamSignalingObserver methods are called
1099 // if the ssrc on a local track is changed when
1100 // MediaStreamSignaling::OnLocalDescriptionChanged is called.
1101 TEST_F(MediaStreamSignalingTest, ChangeSsrcOnTrackInLocalSessionDescription) {
1102 rtc::scoped_ptr<SessionDescriptionInterface> desc;
1103 CreateSessionDescriptionAndReference(1, 1, desc.use());
1104
1105 signaling_->AddLocalStream(reference_collection_->at(0));
1106 signaling_->OnLocalDescriptionChanged(desc.get());
1107 EXPECT_EQ(1u, observer_->NumberOfLocalAudioTracks());
1108 EXPECT_EQ(1u, observer_->NumberOfLocalVideoTracks());
1109 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[0], 1);
1110 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[0], 2);
1111
1112 // Change the ssrc of the audio and video track.
1113 std::string sdp;
1114 desc->ToString(&sdp);
1115 std::string ssrc_org = "a=ssrc:1";
1116 std::string ssrc_to = "a=ssrc:97";
1117 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(),
1118 ssrc_to.c_str(), ssrc_to.length(),
1119 &sdp);
1120 ssrc_org = "a=ssrc:2";
1121 ssrc_to = "a=ssrc:98";
1122 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(),
1123 ssrc_to.c_str(), ssrc_to.length(),
1124 &sdp);
1125 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc(
1126 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1127 sdp, NULL));
1128
1129 signaling_->OnLocalDescriptionChanged(updated_desc.get());
1130 EXPECT_EQ(1u, observer_->NumberOfLocalAudioTracks());
1131 EXPECT_EQ(1u, observer_->NumberOfLocalVideoTracks());
1132 observer_->VerifyLocalAudioTrack(kStreams[0], kAudioTracks[0], 97);
1133 observer_->VerifyLocalVideoTrack(kStreams[0], kVideoTracks[0], 98);
1134 }
1135
1136 // This test that the correct MediaStreamSignalingObserver methods are called
1137 // if a new session description is set with the same tracks but they are now
1138 // sent on a another MediaStream.
1139 TEST_F(MediaStreamSignalingTest, SignalSameTracksInSeparateMediaStream) {
1140 rtc::scoped_ptr<SessionDescriptionInterface> desc;
1141 CreateSessionDescriptionAndReference(1, 1, desc.use());
1142
1143 signaling_->AddLocalStream(reference_collection_->at(0));
1144 signaling_->OnLocalDescriptionChanged(desc.get());
1145 EXPECT_EQ(1u, observer_->NumberOfLocalAudioTracks());
1146 EXPECT_EQ(1u, observer_->NumberOfLocalVideoTracks());
1147
1148 std::string stream_label_0 = kStreams[0];
1149 observer_->VerifyLocalAudioTrack(stream_label_0, kAudioTracks[0], 1);
1150 observer_->VerifyLocalVideoTrack(stream_label_0, kVideoTracks[0], 2);
1151
1152 // Add a new MediaStream but with the same tracks as in the first stream.
1153 std::string stream_label_1 = kStreams[1];
1154 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
1155 webrtc::MediaStream::Create(kStreams[1]));
1156 stream_1->AddTrack(reference_collection_->at(0)->GetVideoTracks()[0]);
1157 stream_1->AddTrack(reference_collection_->at(0)->GetAudioTracks()[0]);
1158 signaling_->AddLocalStream(stream_1);
1159
1160 // Replace msid in the original SDP.
1161 std::string sdp;
1162 desc->ToString(&sdp);
1163 rtc::replace_substrs(
1164 kStreams[0], strlen(kStreams[0]), kStreams[1], strlen(kStreams[1]), &sdp);
1165
1166 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc(
1167 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1168 sdp, NULL));
1169
1170 signaling_->OnLocalDescriptionChanged(updated_desc.get());
1171 observer_->VerifyLocalAudioTrack(kStreams[1], kAudioTracks[0], 1);
1172 observer_->VerifyLocalVideoTrack(kStreams[1], kVideoTracks[0], 2);
1173 EXPECT_EQ(1u, observer_->NumberOfLocalAudioTracks());
1174 EXPECT_EQ(1u, observer_->NumberOfLocalVideoTracks());
1175 }
1176
1177 // Verifies that an even SCTP id is allocated for SSL_CLIENT and an odd id for
1178 // SSL_SERVER.
1179 TEST_F(MediaStreamSignalingTest, SctpIdAllocationBasedOnRole) {
1180 int id;
1181 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER, &id));
1182 EXPECT_EQ(1, id);
1183 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT, &id));
1184 EXPECT_EQ(0, id);
1185 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER, &id));
1186 EXPECT_EQ(3, id);
1187 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT, &id));
1188 EXPECT_EQ(2, id);
1189 }
1190
1191 // Verifies that SCTP ids of existing DataChannels are not reused.
1192 TEST_F(MediaStreamSignalingTest, SctpIdAllocationNoReuse) {
1193 int old_id = 1;
1194 AddDataChannel(cricket::DCT_SCTP, "a", old_id);
1195
1196 int new_id;
1197 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER, &new_id));
1198 EXPECT_NE(old_id, new_id);
1199
1200 // Creates a DataChannel with id 0.
1201 old_id = 0;
1202 AddDataChannel(cricket::DCT_SCTP, "a", old_id);
1203 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT, &new_id));
1204 EXPECT_NE(old_id, new_id);
1205 }
1206
1207 // Verifies that SCTP ids of removed DataChannels can be reused.
1208 TEST_F(MediaStreamSignalingTest, SctpIdReusedForRemovedDataChannel) {
1209 int odd_id = 1;
1210 int even_id = 0;
1211 AddDataChannel(cricket::DCT_SCTP, "a", odd_id);
1212 AddDataChannel(cricket::DCT_SCTP, "a", even_id);
1213
1214 int allocated_id = -1;
1215 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER,
1216 &allocated_id));
1217 EXPECT_EQ(odd_id + 2, allocated_id);
1218 AddDataChannel(cricket::DCT_SCTP, "a", allocated_id);
1219
1220 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT,
1221 &allocated_id));
1222 EXPECT_EQ(even_id + 2, allocated_id);
1223 AddDataChannel(cricket::DCT_SCTP, "a", allocated_id);
1224
1225 signaling_->RemoveSctpDataChannel(odd_id);
1226 signaling_->RemoveSctpDataChannel(even_id);
1227
1228 // Verifies that removed DataChannel ids are reused.
1229 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER,
1230 &allocated_id));
1231 EXPECT_EQ(odd_id, allocated_id);
1232
1233 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT,
1234 &allocated_id));
1235 EXPECT_EQ(even_id, allocated_id);
1236
1237 // Verifies that used higher DataChannel ids are not reused.
1238 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_SERVER,
1239 &allocated_id));
1240 EXPECT_NE(odd_id + 2, allocated_id);
1241
1242 ASSERT_TRUE(signaling_->AllocateSctpSid(rtc::SSL_CLIENT,
1243 &allocated_id));
1244 EXPECT_NE(even_id + 2, allocated_id);
1245
1246 }
1247
1248 // Verifies that duplicated label is not allowed for RTP data channel.
1249 TEST_F(MediaStreamSignalingTest, RtpDuplicatedLabelNotAllowed) {
1250 AddDataChannel(cricket::DCT_RTP, "a", -1);
1251
1252 webrtc::InternalDataChannelInit config;
1253 rtc::scoped_refptr<webrtc::DataChannel> data_channel =
1254 webrtc::DataChannel::Create(
1255 data_channel_provider_.get(), cricket::DCT_RTP, "a", config);
1256 ASSERT_TRUE(data_channel.get() != NULL);
1257 EXPECT_FALSE(signaling_->AddDataChannel(data_channel.get()));
1258 }
1259
1260 // Verifies that duplicated label is allowed for SCTP data channel.
1261 TEST_F(MediaStreamSignalingTest, SctpDuplicatedLabelAllowed) {
1262 AddDataChannel(cricket::DCT_SCTP, "a", -1);
1263 AddDataChannel(cricket::DCT_SCTP, "a", -1);
1264 }
1265
1266 // Verifies the correct configuration is used to create DataChannel from an OPEN
1267 // message.
1268 TEST_F(MediaStreamSignalingTest, CreateDataChannelFromOpenMessage) {
1269 FakeDataChannelFactory fake_factory(data_channel_provider_.get(),
1270 cricket::DCT_SCTP,
1271 signaling_.get());
1272 signaling_->SetDataChannelFactory(&fake_factory);
1273 webrtc::DataChannelInit config;
1274 config.id = 1;
1275 rtc::Buffer payload;
1276 webrtc::WriteDataChannelOpenMessage("a", config, &payload);
1277 cricket::ReceiveDataParams params;
1278 params.ssrc = config.id;
1279 EXPECT_TRUE(signaling_->AddDataChannelFromOpenMessage(params, payload));
1280 EXPECT_EQ(config.id, fake_factory.last_init().id);
1281 EXPECT_FALSE(fake_factory.last_init().negotiated);
1282 EXPECT_EQ(webrtc::InternalDataChannelInit::kAcker,
1283 fake_factory.last_init().open_handshake_role);
1284 }
1285
1286 // Verifies that duplicated label from OPEN message is allowed.
1287 TEST_F(MediaStreamSignalingTest, DuplicatedLabelFromOpenMessageAllowed) {
1288 AddDataChannel(cricket::DCT_SCTP, "a", -1);
1289
1290 FakeDataChannelFactory fake_factory(data_channel_provider_.get(),
1291 cricket::DCT_SCTP,
1292 signaling_.get());
1293 signaling_->SetDataChannelFactory(&fake_factory);
1294 webrtc::DataChannelInit config;
1295 config.id = 0;
1296 rtc::Buffer payload;
1297 webrtc::WriteDataChannelOpenMessage("a", config, &payload);
1298 cricket::ReceiveDataParams params;
1299 params.ssrc = config.id;
1300 EXPECT_TRUE(signaling_->AddDataChannelFromOpenMessage(params, payload));
1301 }
1302
1303 // Verifies that a DataChannel closed remotely is closed locally.
1304 TEST_F(MediaStreamSignalingTest,
1305 SctpDataChannelClosedLocallyWhenClosedRemotely) {
1306 webrtc::InternalDataChannelInit config;
1307 config.id = 0;
1308
1309 rtc::scoped_refptr<webrtc::DataChannel> data_channel =
1310 webrtc::DataChannel::Create(
1311 data_channel_provider_.get(), cricket::DCT_SCTP, "a", config);
1312 ASSERT_TRUE(data_channel.get() != NULL);
1313 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
1314 data_channel->state());
1315
1316 EXPECT_TRUE(signaling_->AddDataChannel(data_channel.get()));
1317
1318 signaling_->OnRemoteSctpDataChannelClosed(config.id);
1319 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, data_channel->state());
1320 }
1321
1322 // Verifies that DataChannel added from OPEN message is added to
1323 // MediaStreamSignaling only once (webrtc issue 3778).
1324 TEST_F(MediaStreamSignalingTest, DataChannelFromOpenMessageAddedOnce) {
1325 FakeDataChannelFactory fake_factory(data_channel_provider_.get(),
1326 cricket::DCT_SCTP,
1327 signaling_.get());
1328 signaling_->SetDataChannelFactory(&fake_factory);
1329 webrtc::DataChannelInit config;
1330 config.id = 1;
1331 rtc::Buffer payload;
1332 webrtc::WriteDataChannelOpenMessage("a", config, &payload);
1333 cricket::ReceiveDataParams params;
1334 params.ssrc = config.id;
1335 EXPECT_TRUE(signaling_->AddDataChannelFromOpenMessage(params, payload));
1336 EXPECT_TRUE(signaling_->HasDataChannels());
1337
1338 // Removes the DataChannel and verifies that no DataChannel is left.
1339 signaling_->RemoveSctpDataChannel(config.id);
1340 EXPECT_FALSE(signaling_->HasDataChannels());
1341 }
OLDNEW
« no previous file with comments | « talk/app/webrtc/mediastreamsignaling.cc ('k') | talk/app/webrtc/peerconnection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698