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