Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / app / webrtc / webrtcsession_unittest.cc
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 "talk/app/webrtc/audiotrack.h"
29 #include "talk/app/webrtc/jsepicecandidate.h"
30 #include "talk/app/webrtc/jsepsessiondescription.h"
31 #include "talk/app/webrtc/mediastreamsignaling.h"
32 #include "talk/app/webrtc/streamcollection.h"
33 #include "talk/app/webrtc/test/fakeconstraints.h"
34 #include "talk/app/webrtc/test/fakedtlsidentityservice.h"
35 #include "talk/app/webrtc/test/fakemediastreamsignaling.h"
36 #include "talk/app/webrtc/videotrack.h"
37 #include "talk/app/webrtc/webrtcsession.h"
38 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
39 #include "talk/media/base/fakemediaengine.h"
40 #include "talk/media/base/fakevideorenderer.h"
41 #include "talk/media/base/mediachannel.h"
42 #include "talk/media/devices/fakedevicemanager.h"
43 #include "talk/p2p/base/stunserver.h"
44 #include "talk/p2p/base/teststunserver.h"
45 #include "talk/p2p/base/testturnserver.h"
46 #include "talk/p2p/client/basicportallocator.h"
47 #include "talk/session/media/channelmanager.h"
48 #include "talk/session/media/mediasession.h"
49 #include "webrtc/base/fakenetwork.h"
50 #include "webrtc/base/firewallsocketserver.h"
51 #include "webrtc/base/gunit.h"
52 #include "webrtc/base/logging.h"
53 #include "webrtc/base/network.h"
54 #include "webrtc/base/physicalsocketserver.h"
55 #include "webrtc/base/ssladapter.h"
56 #include "webrtc/base/sslstreamadapter.h"
57 #include "webrtc/base/stringutils.h"
58 #include "webrtc/base/thread.h"
59 #include "webrtc/base/virtualsocketserver.h"
60
61 #define MAYBE_SKIP_TEST(feature)                    \
62   if (!(feature())) {                               \
63     LOG(LS_INFO) << "Feature disabled... skipping"; \
64     return;                                         \
65   }
66
67 using cricket::BaseSession;
68 using cricket::DF_PLAY;
69 using cricket::DF_SEND;
70 using cricket::FakeVoiceMediaChannel;
71 using cricket::NS_GINGLE_P2P;
72 using cricket::NS_JINGLE_ICE_UDP;
73 using cricket::TransportInfo;
74 using rtc::SocketAddress;
75 using rtc::scoped_ptr;
76 using rtc::Thread;
77 using webrtc::CreateSessionDescription;
78 using webrtc::CreateSessionDescriptionObserver;
79 using webrtc::CreateSessionDescriptionRequest;
80 using webrtc::DTLSIdentityRequestObserver;
81 using webrtc::DTLSIdentityServiceInterface;
82 using webrtc::FakeConstraints;
83 using webrtc::IceCandidateCollection;
84 using webrtc::JsepIceCandidate;
85 using webrtc::JsepSessionDescription;
86 using webrtc::PeerConnectionFactoryInterface;
87 using webrtc::PeerConnectionInterface;
88 using webrtc::SessionDescriptionInterface;
89 using webrtc::StreamCollection;
90 using webrtc::WebRtcSession;
91 using webrtc::kBundleWithoutRtcpMux;
92 using webrtc::kCreateChannelFailed;
93 using webrtc::kInvalidSdp;
94 using webrtc::kMlineMismatch;
95 using webrtc::kPushDownTDFailed;
96 using webrtc::kSdpWithoutIceUfragPwd;
97 using webrtc::kSdpWithoutDtlsFingerprint;
98 using webrtc::kSdpWithoutSdesCrypto;
99 using webrtc::kSessionError;
100 using webrtc::kSessionErrorDesc;
101 using webrtc::kMaxUnsignalledRecvStreams;
102
103 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
104
105 static const int kClientAddrPort = 0;
106 static const char kClientAddrHost1[] = "11.11.11.11";
107 static const char kClientAddrHost2[] = "22.22.22.22";
108 static const char kStunAddrHost[] = "99.99.99.1";
109 static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
110 static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
111
112 static const char kSessionVersion[] = "1";
113
114 // Media index of candidates belonging to the first media content.
115 static const int kMediaContentIndex0 = 0;
116 static const char kMediaContentName0[] = "audio";
117
118 // Media index of candidates belonging to the second media content.
119 static const int kMediaContentIndex1 = 1;
120 static const char kMediaContentName1[] = "video";
121
122 static const int kIceCandidatesTimeout = 10000;
123
124 static const char kFakeDtlsFingerprint[] =
125     "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
126     "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
127
128 static const char kTooLongIceUfragPwd[] =
129     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
130     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
131     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
132     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
133
134 // Add some extra |newlines| to the |message| after |line|.
135 static void InjectAfter(const std::string& line,
136                         const std::string& newlines,
137                         std::string* message) {
138   const std::string tmp = line + newlines;
139   rtc::replace_substrs(line.c_str(), line.length(),
140                              tmp.c_str(), tmp.length(), message);
141 }
142
143 class MockIceObserver : public webrtc::IceObserver {
144  public:
145   MockIceObserver()
146       : oncandidatesready_(false),
147         ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
148         ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
149   }
150
151   virtual void OnIceConnectionChange(
152       PeerConnectionInterface::IceConnectionState new_state) {
153     ice_connection_state_ = new_state;
154   }
155   virtual void OnIceGatheringChange(
156       PeerConnectionInterface::IceGatheringState new_state) {
157     // We can never transition back to "new".
158     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
159     ice_gathering_state_ = new_state;
160
161     // oncandidatesready_ really means "ICE gathering is complete".
162     // This if statement ensures that this value remains correct when we
163     // transition from kIceGatheringComplete to kIceGatheringGathering.
164     if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
165       oncandidatesready_ = false;
166     }
167   }
168
169   // Found a new candidate.
170   virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
171     switch (candidate->sdp_mline_index()) {
172       case kMediaContentIndex0:
173         mline_0_candidates_.push_back(candidate->candidate());
174         break;
175       case kMediaContentIndex1:
176         mline_1_candidates_.push_back(candidate->candidate());
177         break;
178       default:
179         ASSERT(false);
180     }
181
182     // The ICE gathering state should always be Gathering when a candidate is
183     // received (or possibly Completed in the case of the final candidate).
184     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
185   }
186
187   // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
188   virtual void OnIceComplete() {
189     EXPECT_FALSE(oncandidatesready_);
190     oncandidatesready_ = true;
191
192     // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
193     // be called approximately simultaneously.  For ease of testing, this
194     // check additionally requires that they be called in the above order.
195     EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
196               ice_gathering_state_);
197   }
198
199   bool oncandidatesready_;
200   std::vector<cricket::Candidate> mline_0_candidates_;
201   std::vector<cricket::Candidate> mline_1_candidates_;
202   PeerConnectionInterface::IceConnectionState ice_connection_state_;
203   PeerConnectionInterface::IceGatheringState ice_gathering_state_;
204 };
205
206 class WebRtcSessionForTest : public webrtc::WebRtcSession {
207  public:
208   WebRtcSessionForTest(cricket::ChannelManager* cmgr,
209                        rtc::Thread* signaling_thread,
210                        rtc::Thread* worker_thread,
211                        cricket::PortAllocator* port_allocator,
212                        webrtc::IceObserver* ice_observer,
213                        webrtc::MediaStreamSignaling* mediastream_signaling)
214     : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
215                     mediastream_signaling) {
216     RegisterIceObserver(ice_observer);
217   }
218   virtual ~WebRtcSessionForTest() {}
219
220   using cricket::BaseSession::GetTransportProxy;
221   using webrtc::WebRtcSession::SetAudioPlayout;
222   using webrtc::WebRtcSession::SetAudioSend;
223   using webrtc::WebRtcSession::SetCaptureDevice;
224   using webrtc::WebRtcSession::SetVideoPlayout;
225   using webrtc::WebRtcSession::SetVideoSend;
226 };
227
228 class WebRtcSessionCreateSDPObserverForTest
229     : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
230  public:
231   enum State {
232     kInit,
233     kFailed,
234     kSucceeded,
235   };
236   WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
237
238   // CreateSessionDescriptionObserver implementation.
239   virtual void OnSuccess(SessionDescriptionInterface* desc) {
240     description_.reset(desc);
241     state_ = kSucceeded;
242   }
243   virtual void OnFailure(const std::string& error) {
244     state_ = kFailed;
245   }
246
247   SessionDescriptionInterface* description() { return description_.get(); }
248
249   SessionDescriptionInterface* ReleaseDescription() {
250     return description_.release();
251   }
252
253   State state() const { return state_; }
254
255  protected:
256   ~WebRtcSessionCreateSDPObserverForTest() {}
257
258  private:
259   rtc::scoped_ptr<SessionDescriptionInterface> description_;
260   State state_;
261 };
262
263 class FakeAudioRenderer : public cricket::AudioRenderer {
264  public:
265   FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
266   virtual ~FakeAudioRenderer() {
267     if (sink_)
268       sink_->OnClose();
269   }
270
271   virtual void AddChannel(int channel_id) OVERRIDE {
272     ASSERT(channel_id_ == -1);
273     channel_id_ = channel_id;
274   }
275   virtual void RemoveChannel(int channel_id) OVERRIDE {
276     ASSERT(channel_id == channel_id_);
277     channel_id_ = -1;
278   }
279   virtual void SetSink(Sink* sink) OVERRIDE {
280     sink_ = sink;
281   }
282
283   int channel_id() const { return channel_id_; }
284   cricket::AudioRenderer::Sink* sink() const { return sink_; }
285  private:
286   int channel_id_;
287   cricket::AudioRenderer::Sink* sink_;
288 };
289
290 class WebRtcSessionTest : public testing::Test {
291  protected:
292   // TODO Investigate why ChannelManager crashes, if it's created
293   // after stun_server.
294   WebRtcSessionTest()
295     : media_engine_(new cricket::FakeMediaEngine()),
296       data_engine_(new cricket::FakeDataEngine()),
297       device_manager_(new cricket::FakeDeviceManager()),
298       channel_manager_(new cricket::ChannelManager(
299          media_engine_, data_engine_, device_manager_,
300          new cricket::CaptureManager(), rtc::Thread::Current())),
301       tdesc_factory_(new cricket::TransportDescriptionFactory()),
302       desc_factory_(new cricket::MediaSessionDescriptionFactory(
303           channel_manager_.get(), tdesc_factory_.get())),
304       pss_(new rtc::PhysicalSocketServer),
305       vss_(new rtc::VirtualSocketServer(pss_.get())),
306       fss_(new rtc::FirewallSocketServer(vss_.get())),
307       ss_scope_(fss_.get()),
308       stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
309                                                  cricket::STUN_SERVER_PORT)),
310       stun_server_(Thread::Current(), stun_socket_addr_),
311       turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
312       mediastream_signaling_(channel_manager_.get()),
313       ice_type_(PeerConnectionInterface::kAll) {
314     tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
315
316     cricket::ServerAddresses stun_servers;
317     stun_servers.insert(stun_socket_addr_);
318     allocator_.reset(new cricket::BasicPortAllocator(
319         &network_manager_,
320         stun_servers,
321         SocketAddress(), SocketAddress(), SocketAddress()));
322     allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
323                          cricket::PORTALLOCATOR_DISABLE_RELAY |
324                          cricket::PORTALLOCATOR_ENABLE_BUNDLE);
325     EXPECT_TRUE(channel_manager_->Init());
326     desc_factory_->set_add_legacy_streams(false);
327     allocator_->set_step_delay(cricket::kMinimumStepDelay);
328   }
329
330   static void SetUpTestCase() {
331     rtc::InitializeSSL();
332   }
333
334   static void TearDownTestCase() {
335     rtc::CleanupSSL();
336   }
337
338   void AddInterface(const SocketAddress& addr) {
339     network_manager_.AddInterface(addr);
340   }
341
342   void SetIceTransportType(PeerConnectionInterface::IceTransportsType type) {
343     ice_type_ = type;
344   }
345
346   void Init(DTLSIdentityServiceInterface* identity_service) {
347     ASSERT_TRUE(session_.get() == NULL);
348     session_.reset(new WebRtcSessionForTest(
349         channel_manager_.get(), rtc::Thread::Current(),
350         rtc::Thread::Current(), allocator_.get(),
351         &observer_,
352         &mediastream_signaling_));
353
354     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
355         observer_.ice_connection_state_);
356     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
357         observer_.ice_gathering_state_);
358
359     EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
360                                      identity_service, ice_type_));
361   }
362
363   void InitWithDtmfCodec() {
364     // Add kTelephoneEventCodec for dtmf test.
365     const cricket::AudioCodec kTelephoneEventCodec(
366         106, "telephone-event", 8000, 0, 1, 0);
367     std::vector<cricket::AudioCodec> codecs;
368     codecs.push_back(kTelephoneEventCodec);
369     media_engine_->SetAudioCodecs(codecs);
370     desc_factory_->set_audio_codecs(codecs);
371     Init(NULL);
372   }
373
374   void InitWithDtls(bool identity_request_should_fail = false) {
375     FakeIdentityService* identity_service = new FakeIdentityService();
376     identity_service->set_should_fail(identity_request_should_fail);
377     Init(identity_service);
378   }
379
380   // Creates a local offer and applies it. Starts ice.
381   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
382   // to decide which streams to create.
383   void InitiateCall() {
384     SessionDescriptionInterface* offer = CreateOffer();
385     SetLocalDescriptionWithoutError(offer);
386     EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
387         observer_.ice_gathering_state_,
388         kIceCandidatesTimeout);
389   }
390
391   SessionDescriptionInterface* CreateOffer() {
392     PeerConnectionInterface::RTCOfferAnswerOptions options;
393     options.offer_to_receive_audio =
394         RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
395
396     return CreateOffer(options);
397   }
398
399   SessionDescriptionInterface* CreateOffer(
400       const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
401     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
402         observer = new WebRtcSessionCreateSDPObserverForTest();
403     session_->CreateOffer(observer, options);
404     EXPECT_TRUE_WAIT(
405         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
406         2000);
407     return observer->ReleaseDescription();
408   }
409
410   SessionDescriptionInterface* CreateAnswer(
411       const webrtc::MediaConstraintsInterface* constraints) {
412     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
413         = new WebRtcSessionCreateSDPObserverForTest();
414     session_->CreateAnswer(observer, constraints);
415     EXPECT_TRUE_WAIT(
416         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
417         2000);
418     return observer->ReleaseDescription();
419   }
420
421   bool ChannelsExist() const {
422     return (session_->voice_channel() != NULL &&
423             session_->video_channel() != NULL);
424   }
425
426   void CheckTransportChannels() const {
427     EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
428     EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
429     EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
430     EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
431   }
432
433   void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
434     ASSERT_TRUE(session_.get() != NULL);
435     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
436     ASSERT_TRUE(content != NULL);
437     const cricket::AudioContentDescription* audio_content =
438         static_cast<const cricket::AudioContentDescription*>(
439             content->description);
440     ASSERT_TRUE(audio_content != NULL);
441     ASSERT_EQ(1U, audio_content->cryptos().size());
442     ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
443     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
444               audio_content->cryptos()[0].cipher_suite);
445     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
446               audio_content->protocol());
447
448     content = cricket::GetFirstVideoContent(sdp);
449     ASSERT_TRUE(content != NULL);
450     const cricket::VideoContentDescription* video_content =
451         static_cast<const cricket::VideoContentDescription*>(
452             content->description);
453     ASSERT_TRUE(video_content != NULL);
454     ASSERT_EQ(1U, video_content->cryptos().size());
455     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
456               video_content->cryptos()[0].cipher_suite);
457     ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
458     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
459               video_content->protocol());
460   }
461
462   void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
463     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
464     ASSERT_TRUE(content != NULL);
465     const cricket::AudioContentDescription* audio_content =
466         static_cast<const cricket::AudioContentDescription*>(
467             content->description);
468     ASSERT_TRUE(audio_content != NULL);
469     ASSERT_EQ(0U, audio_content->cryptos().size());
470
471     content = cricket::GetFirstVideoContent(sdp);
472     ASSERT_TRUE(content != NULL);
473     const cricket::VideoContentDescription* video_content =
474         static_cast<const cricket::VideoContentDescription*>(
475             content->description);
476     ASSERT_TRUE(video_content != NULL);
477     ASSERT_EQ(0U, video_content->cryptos().size());
478
479     if (dtls) {
480       EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
481                 audio_content->protocol());
482       EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
483                 video_content->protocol());
484     } else {
485       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
486                 audio_content->protocol());
487       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
488                 video_content->protocol());
489     }
490   }
491
492   // Set the internal fake description factories to do DTLS-SRTP.
493   void SetFactoryDtlsSrtp() {
494     desc_factory_->set_secure(cricket::SEC_DISABLED);
495     std::string identity_name = "WebRTC" +
496         rtc::ToString(rtc::CreateRandomId());
497     identity_.reset(rtc::SSLIdentity::Generate(identity_name));
498     tdesc_factory_->set_identity(identity_.get());
499     tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
500   }
501
502   void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
503                                bool expected) {
504     const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
505     ASSERT_TRUE(audio != NULL);
506     ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
507     const TransportInfo* video = sdp->GetTransportInfoByName("video");
508     ASSERT_TRUE(video != NULL);
509     ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
510   }
511
512   void VerifyAnswerFromNonCryptoOffer() {
513     // Create a SDP without Crypto.
514     cricket::MediaSessionOptions options;
515     options.has_video = true;
516     JsepSessionDescription* offer(
517         CreateRemoteOffer(options, cricket::SEC_DISABLED));
518     ASSERT_TRUE(offer != NULL);
519     VerifyNoCryptoParams(offer->description(), false);
520     SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
521                                          offer);
522     const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
523     // Answer should be NULL as no crypto params in offer.
524     ASSERT_TRUE(answer == NULL);
525   }
526
527   void VerifyAnswerFromCryptoOffer() {
528     cricket::MediaSessionOptions options;
529     options.has_video = true;
530     options.bundle_enabled = true;
531     scoped_ptr<JsepSessionDescription> offer(
532         CreateRemoteOffer(options, cricket::SEC_REQUIRED));
533     ASSERT_TRUE(offer.get() != NULL);
534     VerifyCryptoParams(offer->description());
535     SetRemoteDescriptionWithoutError(offer.release());
536     scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
537     ASSERT_TRUE(answer.get() != NULL);
538     VerifyCryptoParams(answer->description());
539   }
540
541   void SetAndVerifyNumUnsignalledRecvStreams(
542       int value_set, int value_expected) {
543     constraints_.reset(new FakeConstraints());
544     constraints_->AddOptional(
545         webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
546         value_set);
547     session_.reset();
548     Init(NULL);
549     mediastream_signaling_.SendAudioVideoStream1();
550     SessionDescriptionInterface* offer = CreateOffer();
551
552     SetLocalDescriptionWithoutError(offer);
553
554     video_channel_ = media_engine_->GetVideoChannel(0);
555
556     ASSERT_TRUE(video_channel_ != NULL);
557     cricket::VideoOptions video_options;
558     EXPECT_TRUE(video_channel_->GetOptions(&video_options));
559     EXPECT_EQ(value_expected,
560         video_options.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(-1));
561   }
562
563   void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
564                                   const cricket::SessionDescription* desc2,
565                                   bool expect_equal) {
566     if (desc1->contents().size() != desc2->contents().size()) {
567       EXPECT_FALSE(expect_equal);
568       return;
569     }
570
571     const cricket::ContentInfos& contents = desc1->contents();
572     cricket::ContentInfos::const_iterator it = contents.begin();
573
574     for (; it != contents.end(); ++it) {
575       const cricket::TransportDescription* transport_desc1 =
576           desc1->GetTransportDescriptionByName(it->name);
577       const cricket::TransportDescription* transport_desc2 =
578           desc2->GetTransportDescriptionByName(it->name);
579       if (!transport_desc1 || !transport_desc2) {
580         EXPECT_FALSE(expect_equal);
581         return;
582       }
583       if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
584           transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
585         EXPECT_FALSE(expect_equal);
586         return;
587       }
588     }
589     EXPECT_TRUE(expect_equal);
590   }
591
592   void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
593                               std::string *sdp) {
594     const cricket::SessionDescription* desc = current_desc->description();
595     EXPECT_TRUE(current_desc->ToString(sdp));
596
597     const cricket::ContentInfos& contents = desc->contents();
598     cricket::ContentInfos::const_iterator it = contents.begin();
599     // Replace ufrag and pwd lines with empty strings.
600     for (; it != contents.end(); ++it) {
601       const cricket::TransportDescription* transport_desc =
602           desc->GetTransportDescriptionByName(it->name);
603       std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
604           + "\r\n";
605       std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
606           + "\r\n";
607       rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
608                                  "", 0,
609                                  sdp);
610       rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
611                                  "", 0,
612                                  sdp);
613     }
614   }
615
616   void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
617                               const std::string& modified_ice_ufrag,
618                               const std::string& modified_ice_pwd,
619                               std::string* sdp) {
620     const cricket::SessionDescription* desc = current_desc->description();
621     EXPECT_TRUE(current_desc->ToString(sdp));
622
623     const cricket::ContentInfos& contents = desc->contents();
624     cricket::ContentInfos::const_iterator it = contents.begin();
625     // Replace ufrag and pwd lines with |modified_ice_ufrag| and
626     // |modified_ice_pwd| strings.
627     for (; it != contents.end(); ++it) {
628       const cricket::TransportDescription* transport_desc =
629           desc->GetTransportDescriptionByName(it->name);
630       std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
631           + "\r\n";
632       std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
633           + "\r\n";
634       std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
635       std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
636       rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
637                                  mod_ufrag.c_str(), mod_ufrag.length(),
638                                  sdp);
639       rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
640                                  mod_pwd.c_str(), mod_pwd.length(),
641                                  sdp);
642     }
643   }
644
645   // Creates a remote offer and and applies it as a remote description,
646   // creates a local answer and applies is as a local description.
647   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
648   // to decide which local and remote streams to create.
649   void CreateAndSetRemoteOfferAndLocalAnswer() {
650     SessionDescriptionInterface* offer = CreateRemoteOffer();
651     SetRemoteDescriptionWithoutError(offer);
652     SessionDescriptionInterface* answer = CreateAnswer(NULL);
653     SetLocalDescriptionWithoutError(answer);
654   }
655   void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
656     EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
657   }
658   void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
659                                       BaseSession::State expected_state) {
660     SetLocalDescriptionWithoutError(desc);
661     EXPECT_EQ(expected_state, session_->state());
662   }
663   void SetLocalDescriptionExpectError(const std::string& action,
664                                       const std::string& expected_error,
665                                       SessionDescriptionInterface* desc) {
666     std::string error;
667     EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
668     std::string sdp_type = "local ";
669     sdp_type.append(action);
670     EXPECT_NE(std::string::npos, error.find(sdp_type));
671     EXPECT_NE(std::string::npos, error.find(expected_error));
672   }
673   void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
674                                            SessionDescriptionInterface* desc) {
675     SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
676                                    expected_error, desc);
677   }
678   void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
679                                             SessionDescriptionInterface* desc) {
680     SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
681                                    expected_error, desc);
682   }
683   void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
684     EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
685   }
686   void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
687                                        BaseSession::State expected_state) {
688     SetRemoteDescriptionWithoutError(desc);
689     EXPECT_EQ(expected_state, session_->state());
690   }
691   void SetRemoteDescriptionExpectError(const std::string& action,
692                                        const std::string& expected_error,
693                                        SessionDescriptionInterface* desc) {
694     std::string error;
695     EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
696     std::string sdp_type = "remote ";
697     sdp_type.append(action);
698     EXPECT_NE(std::string::npos, error.find(sdp_type));
699     EXPECT_NE(std::string::npos, error.find(expected_error));
700   }
701   void SetRemoteDescriptionOfferExpectError(
702       const std::string& expected_error, SessionDescriptionInterface* desc) {
703     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
704                                     expected_error, desc);
705   }
706   void SetRemoteDescriptionPranswerExpectError(
707       const std::string& expected_error, SessionDescriptionInterface* desc) {
708     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
709                                     expected_error, desc);
710   }
711   void SetRemoteDescriptionAnswerExpectError(
712       const std::string& expected_error, SessionDescriptionInterface* desc) {
713     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
714                                     expected_error, desc);
715   }
716
717   void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
718       SessionDescriptionInterface** nocrypto_answer) {
719     // Create a SDP without Crypto.
720     cricket::MediaSessionOptions options;
721     options.has_video = true;
722     options.bundle_enabled = true;
723     *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
724     ASSERT_TRUE(*offer != NULL);
725     VerifyCryptoParams((*offer)->description());
726
727     *nocrypto_answer = CreateRemoteAnswer(*offer, options,
728                                           cricket::SEC_DISABLED);
729     EXPECT_TRUE(*nocrypto_answer != NULL);
730   }
731
732   void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
733       SessionDescriptionInterface** nodtls_answer) {
734     cricket::MediaSessionOptions options;
735     options.has_video = true;
736     options.bundle_enabled = true;
737
738     rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
739         CreateRemoteOffer(options, cricket::SEC_ENABLED));
740
741     *nodtls_answer =
742         CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
743     EXPECT_TRUE(*nodtls_answer != NULL);
744     VerifyFingerprintStatus((*nodtls_answer)->description(), false);
745     VerifyCryptoParams((*nodtls_answer)->description());
746
747     SetFactoryDtlsSrtp();
748     *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
749     ASSERT_TRUE(*offer != NULL);
750     VerifyFingerprintStatus((*offer)->description(), true);
751     VerifyCryptoParams((*offer)->description());
752   }
753
754   JsepSessionDescription* CreateRemoteOfferWithVersion(
755         cricket::MediaSessionOptions options,
756         cricket::SecurePolicy secure_policy,
757         const std::string& session_version,
758         const SessionDescriptionInterface* current_desc) {
759     std::string session_id = rtc::ToString(rtc::CreateRandomId64());
760     const cricket::SessionDescription* cricket_desc = NULL;
761     if (current_desc) {
762       cricket_desc = current_desc->description();
763       session_id = current_desc->session_id();
764     }
765
766     desc_factory_->set_secure(secure_policy);
767     JsepSessionDescription* offer(
768         new JsepSessionDescription(JsepSessionDescription::kOffer));
769     if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
770                            session_id, session_version)) {
771       delete offer;
772       offer = NULL;
773     }
774     return offer;
775   }
776   JsepSessionDescription* CreateRemoteOffer(
777       cricket::MediaSessionOptions options) {
778     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
779                                         kSessionVersion, NULL);
780   }
781   JsepSessionDescription* CreateRemoteOffer(
782       cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
783     return CreateRemoteOfferWithVersion(
784         options, sdes_policy, kSessionVersion, NULL);
785   }
786   JsepSessionDescription* CreateRemoteOffer(
787       cricket::MediaSessionOptions options,
788       const SessionDescriptionInterface* current_desc) {
789     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
790                                         kSessionVersion, current_desc);
791   }
792
793   JsepSessionDescription* CreateRemoteOfferWithSctpPort(
794       const char* sctp_stream_name, int new_port,
795       cricket::MediaSessionOptions options) {
796     options.data_channel_type = cricket::DCT_SCTP;
797     options.AddStream(cricket::MEDIA_TYPE_DATA, "datachannel",
798                       sctp_stream_name);
799     return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
800   }
801
802   // Takes ownership of offer_basis (and deletes it).
803   JsepSessionDescription* ChangeSDPSctpPort(
804       int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
805     // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
806     // SessionDescription from the mutated string.
807     const char* default_port_str = "5000";
808     char new_port_str[16];
809     rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
810     std::string offer_str;
811     offer_basis->ToString(&offer_str);
812     rtc::replace_substrs(default_port_str, strlen(default_port_str),
813                                new_port_str, strlen(new_port_str),
814                                &offer_str);
815     JsepSessionDescription* offer = new JsepSessionDescription(
816         offer_basis->type());
817     delete offer_basis;
818     offer->Initialize(offer_str, NULL);
819     return offer;
820   }
821
822   // Create a remote offer. Call mediastream_signaling_.UseOptionsWithStreamX()
823   // before this function to decide which streams to create.
824   JsepSessionDescription* CreateRemoteOffer() {
825     cricket::MediaSessionOptions options;
826     mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
827     return CreateRemoteOffer(options, session_->remote_description());
828   }
829
830   JsepSessionDescription* CreateRemoteAnswer(
831       const SessionDescriptionInterface* offer,
832       cricket::MediaSessionOptions options,
833       cricket::SecurePolicy policy) {
834     desc_factory_->set_secure(policy);
835     const std::string session_id =
836         rtc::ToString(rtc::CreateRandomId64());
837     JsepSessionDescription* answer(
838         new JsepSessionDescription(JsepSessionDescription::kAnswer));
839     if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
840                                                         options, NULL),
841                             session_id, kSessionVersion)) {
842       delete answer;
843       answer = NULL;
844     }
845     return answer;
846   }
847
848   JsepSessionDescription* CreateRemoteAnswer(
849       const SessionDescriptionInterface* offer,
850       cricket::MediaSessionOptions options) {
851       return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
852   }
853
854   // Creates an answer session description with streams based on
855   // |mediastream_signaling_|. Call
856   // mediastream_signaling_.UseOptionsWithStreamX() before this function
857   // to decide which streams to create.
858   JsepSessionDescription* CreateRemoteAnswer(
859       const SessionDescriptionInterface* offer) {
860     cricket::MediaSessionOptions options;
861     mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
862     return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
863   }
864
865   void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
866     AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
867     Init(NULL);
868     mediastream_signaling_.SendAudioVideoStream1();
869
870     PeerConnectionInterface::RTCOfferAnswerOptions options;
871     options.use_rtp_mux = bundle;
872
873     SessionDescriptionInterface* offer = CreateOffer(options);
874     // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
875     // and answer.
876     SetLocalDescriptionWithoutError(offer);
877
878     rtc::scoped_ptr<SessionDescriptionInterface> answer(
879         CreateRemoteAnswer(session_->local_description()));
880     std::string sdp;
881     EXPECT_TRUE(answer->ToString(&sdp));
882
883     size_t expected_candidate_num = 2;
884     if (!rtcp_mux) {
885       // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
886       // for rtp and rtcp.
887       expected_candidate_num = 4;
888       // Disable rtcp-mux from the answer
889       const std::string kRtcpMux = "a=rtcp-mux";
890       const std::string kXRtcpMux = "a=xrtcp-mux";
891       rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
892                                  kXRtcpMux.c_str(), kXRtcpMux.length(),
893                                  &sdp);
894     }
895
896     SessionDescriptionInterface* new_answer = CreateSessionDescription(
897         JsepSessionDescription::kAnswer, sdp, NULL);
898
899     // SetRemoteDescription to enable rtcp mux.
900     SetRemoteDescriptionWithoutError(new_answer);
901     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
902     EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
903     EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
904     for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
905       cricket::Candidate c0 = observer_.mline_0_candidates_[i];
906       cricket::Candidate c1 = observer_.mline_1_candidates_[i];
907       if (bundle) {
908         EXPECT_TRUE(c0.IsEquivalent(c1));
909       } else {
910         EXPECT_FALSE(c0.IsEquivalent(c1));
911       }
912     }
913   }
914   // Tests that we can only send DTMF when the dtmf codec is supported.
915   void TestCanInsertDtmf(bool can) {
916     if (can) {
917       InitWithDtmfCodec();
918     } else {
919       Init(NULL);
920     }
921     mediastream_signaling_.SendAudioVideoStream1();
922     CreateAndSetRemoteOfferAndLocalAnswer();
923     EXPECT_FALSE(session_->CanInsertDtmf(""));
924     EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
925   }
926
927   // The method sets up a call from the session to itself, in a loopback
928   // arrangement.  It also uses a firewall rule to create a temporary
929   // disconnection, and then a permanent disconnection.
930   // This code is placed in a method so that it can be invoked
931   // by multiple tests with different allocators (e.g. with and without BUNDLE).
932   // While running the call, this method also checks if the session goes through
933   // the correct sequence of ICE states when a connection is established,
934   // broken, and re-established.
935   // The Connection state should go:
936   // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
937   //     -> Failed.
938   // The Gathering state should go: New -> Gathering -> Completed.
939   void TestLoopbackCall() {
940     AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
941     Init(NULL);
942     mediastream_signaling_.SendAudioVideoStream1();
943     SessionDescriptionInterface* offer = CreateOffer();
944
945     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
946               observer_.ice_gathering_state_);
947     SetLocalDescriptionWithoutError(offer);
948     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
949               observer_.ice_connection_state_);
950     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
951                    observer_.ice_gathering_state_,
952                    kIceCandidatesTimeout);
953     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
954     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
955                    observer_.ice_gathering_state_,
956                    kIceCandidatesTimeout);
957
958     std::string sdp;
959     offer->ToString(&sdp);
960     SessionDescriptionInterface* desc =
961         webrtc::CreateSessionDescription(JsepSessionDescription::kAnswer, sdp);
962     ASSERT_TRUE(desc != NULL);
963     SetRemoteDescriptionWithoutError(desc);
964
965     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
966                    observer_.ice_connection_state_,
967                    kIceCandidatesTimeout);
968
969     // The ice connection state is "Connected" too briefly to catch in a test.
970     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
971                    observer_.ice_connection_state_,
972                    kIceCandidatesTimeout);
973
974     // Adding firewall rule to block ping requests, which should cause
975     // transport channel failure.
976     fss_->AddRule(false,
977                   rtc::FP_ANY,
978                   rtc::FD_ANY,
979                   rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
980     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
981                    observer_.ice_connection_state_,
982                    kIceCandidatesTimeout);
983
984     // Clearing the rules, session should move back to completed state.
985     fss_->ClearRules();
986     // Session is automatically calling OnSignalingReady after creation of
987     // new portallocator session which will allocate new set of candidates.
988
989     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
990                    observer_.ice_connection_state_,
991                    kIceCandidatesTimeout);
992
993     // Now we block ping requests and wait until the ICE connection transitions
994     // to the Failed state.  This will take at least 30 seconds because it must
995     // wait for the Port to timeout.
996     int port_timeout = 30000;
997     fss_->AddRule(false,
998                   rtc::FP_ANY,
999                   rtc::FD_ANY,
1000                   rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1001     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1002                    observer_.ice_connection_state_,
1003                    kIceCandidatesTimeout + port_timeout);
1004   }
1005
1006   void VerifyTransportType(const std::string& content_name,
1007                            cricket::TransportProtocol protocol) {
1008     const cricket::Transport* transport = session_->GetTransport(content_name);
1009     ASSERT_TRUE(transport != NULL);
1010     EXPECT_EQ(protocol, transport->protocol());
1011   }
1012
1013   // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1014   void AddCNCodecs() {
1015     const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
1016     const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
1017
1018     // Add kCNCodec for dtmf test.
1019     std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
1020     codecs.push_back(kCNCodec1);
1021     codecs.push_back(kCNCodec2);
1022     media_engine_->SetAudioCodecs(codecs);
1023     desc_factory_->set_audio_codecs(codecs);
1024   }
1025
1026   bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1027     const cricket::ContentDescription* description = content->description;
1028     ASSERT(description != NULL);
1029     const cricket::AudioContentDescription* audio_content_desc =
1030         static_cast<const cricket::AudioContentDescription*>(description);
1031     ASSERT(audio_content_desc != NULL);
1032     for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1033       if (audio_content_desc->codecs()[i].name == "CN")
1034         return false;
1035     }
1036     return true;
1037   }
1038
1039   void SetLocalDescriptionWithDataChannel() {
1040     webrtc::InternalDataChannelInit dci;
1041     dci.reliable = false;
1042     session_->CreateDataChannel("datachannel", &dci);
1043     SessionDescriptionInterface* offer = CreateOffer();
1044     SetLocalDescriptionWithoutError(offer);
1045   }
1046
1047   void VerifyMultipleAsyncCreateDescription(
1048       bool success, CreateSessionDescriptionRequest::Type type) {
1049     InitWithDtls(!success);
1050     SetFactoryDtlsSrtp();
1051     if (type == CreateSessionDescriptionRequest::kAnswer) {
1052       cricket::MediaSessionOptions options;
1053       scoped_ptr<JsepSessionDescription> offer(
1054             CreateRemoteOffer(options, cricket::SEC_DISABLED));
1055       ASSERT_TRUE(offer.get() != NULL);
1056       SetRemoteDescriptionWithoutError(offer.release());
1057     }
1058
1059     PeerConnectionInterface::RTCOfferAnswerOptions options;
1060     const int kNumber = 3;
1061     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
1062         observers[kNumber];
1063     for (int i = 0; i < kNumber; ++i) {
1064       observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1065       if (type == CreateSessionDescriptionRequest::kOffer) {
1066         session_->CreateOffer(observers[i], options);
1067       } else {
1068         session_->CreateAnswer(observers[i], NULL);
1069       }
1070     }
1071
1072     WebRtcSessionCreateSDPObserverForTest::State expected_state =
1073         success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1074                   WebRtcSessionCreateSDPObserverForTest::kFailed;
1075
1076     for (int i = 0; i < kNumber; ++i) {
1077       EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1078       if (success) {
1079         EXPECT_TRUE(observers[i]->description() != NULL);
1080       } else {
1081         EXPECT_TRUE(observers[i]->description() == NULL);
1082       }
1083     }
1084   }
1085
1086   cricket::FakeMediaEngine* media_engine_;
1087   cricket::FakeDataEngine* data_engine_;
1088   cricket::FakeDeviceManager* device_manager_;
1089   rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
1090   rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
1091   rtc::scoped_ptr<rtc::SSLIdentity> identity_;
1092   rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1093   rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1094   rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1095   rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
1096   rtc::SocketServerScope ss_scope_;
1097   rtc::SocketAddress stun_socket_addr_;
1098   cricket::TestStunServer stun_server_;
1099   cricket::TestTurnServer turn_server_;
1100   rtc::FakeNetworkManager network_manager_;
1101   rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
1102   PeerConnectionFactoryInterface::Options options_;
1103   rtc::scoped_ptr<FakeConstraints> constraints_;
1104   FakeMediaStreamSignaling mediastream_signaling_;
1105   rtc::scoped_ptr<WebRtcSessionForTest> session_;
1106   MockIceObserver observer_;
1107   cricket::FakeVideoMediaChannel* video_channel_;
1108   cricket::FakeVoiceMediaChannel* voice_channel_;
1109   PeerConnectionInterface::IceTransportsType ice_type_;
1110 };
1111
1112 TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
1113   InitWithDtls();
1114   // SDES is disabled when DTLS is on.
1115   EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
1116 }
1117
1118 TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
1119   Init(NULL);
1120   // SDES is required if DTLS is off.
1121   EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
1122 }
1123
1124 TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1125   TestSessionCandidatesWithBundleRtcpMux(false, false);
1126 }
1127
1128 // Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1129 // with rtcp-mux and/or bundle.
1130 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1131   TestSessionCandidatesWithBundleRtcpMux(false, true);
1132 }
1133
1134 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1135   TestSessionCandidatesWithBundleRtcpMux(true, true);
1136 }
1137
1138 TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
1139   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1140   AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1141   Init(NULL);
1142   mediastream_signaling_.SendAudioVideoStream1();
1143   InitiateCall();
1144   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1145   EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1146   EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1147 }
1148
1149 TEST_F(WebRtcSessionTest, TestStunError) {
1150   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1151   AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1152   fss_->AddRule(false,
1153                 rtc::FP_UDP,
1154                 rtc::FD_ANY,
1155                 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1156   Init(NULL);
1157   mediastream_signaling_.SendAudioVideoStream1();
1158   InitiateCall();
1159   // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
1160   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1161   EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1162   EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1163 }
1164
1165 TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
1166   Init(NULL);
1167   SessionDescriptionInterface* offer = NULL;
1168   // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1169   std::string unknown_action;
1170   SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1171   SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1172 }
1173
1174 // Test creating offers and receive answers and make sure the
1175 // media engine creates the expected send and receive streams.
1176 TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
1177   Init(NULL);
1178   mediastream_signaling_.SendAudioVideoStream1();
1179   SessionDescriptionInterface* offer = CreateOffer();
1180   const std::string session_id_orig = offer->session_id();
1181   const std::string session_version_orig = offer->session_version();
1182   SetLocalDescriptionWithoutError(offer);
1183
1184   mediastream_signaling_.SendAudioVideoStream2();
1185   SessionDescriptionInterface* answer =
1186       CreateRemoteAnswer(session_->local_description());
1187   SetRemoteDescriptionWithoutError(answer);
1188
1189   video_channel_ = media_engine_->GetVideoChannel(0);
1190   voice_channel_ = media_engine_->GetVoiceChannel(0);
1191
1192   ASSERT_EQ(1u, video_channel_->recv_streams().size());
1193   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1194
1195   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1196   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1197
1198   ASSERT_EQ(1u, video_channel_->send_streams().size());
1199   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1200   ASSERT_EQ(1u, voice_channel_->send_streams().size());
1201   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1202
1203   // Create new offer without send streams.
1204   mediastream_signaling_.SendNothing();
1205   offer = CreateOffer();
1206
1207   // Verify the session id is the same and the session version is
1208   // increased.
1209   EXPECT_EQ(session_id_orig, offer->session_id());
1210   EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1211             rtc::FromString<uint64>(offer->session_version()));
1212
1213   SetLocalDescriptionWithoutError(offer);
1214
1215   mediastream_signaling_.SendAudioVideoStream2();
1216   answer = CreateRemoteAnswer(session_->local_description());
1217   SetRemoteDescriptionWithoutError(answer);
1218
1219   EXPECT_EQ(0u, video_channel_->send_streams().size());
1220   EXPECT_EQ(0u, voice_channel_->send_streams().size());
1221
1222   // Make sure the receive streams have not changed.
1223   ASSERT_EQ(1u, video_channel_->recv_streams().size());
1224   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1225   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1226   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1227 }
1228
1229 // Test receiving offers and creating answers and make sure the
1230 // media engine creates the expected send and receive streams.
1231 TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
1232   Init(NULL);
1233   mediastream_signaling_.SendAudioVideoStream2();
1234   SessionDescriptionInterface* offer = CreateOffer();
1235   VerifyCryptoParams(offer->description());
1236   SetRemoteDescriptionWithoutError(offer);
1237
1238   mediastream_signaling_.SendAudioVideoStream1();
1239   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1240   VerifyCryptoParams(answer->description());
1241   SetLocalDescriptionWithoutError(answer);
1242
1243   const std::string session_id_orig = answer->session_id();
1244   const std::string session_version_orig = answer->session_version();
1245
1246   video_channel_ = media_engine_->GetVideoChannel(0);
1247   voice_channel_ = media_engine_->GetVoiceChannel(0);
1248
1249   ASSERT_EQ(1u, video_channel_->recv_streams().size());
1250   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1251
1252   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1253   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1254
1255   ASSERT_EQ(1u, video_channel_->send_streams().size());
1256   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1257   ASSERT_EQ(1u, voice_channel_->send_streams().size());
1258   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1259
1260   mediastream_signaling_.SendAudioVideoStream1And2();
1261   offer = CreateOffer();
1262   SetRemoteDescriptionWithoutError(offer);
1263
1264   // Answer by turning off all send streams.
1265   mediastream_signaling_.SendNothing();
1266   answer = CreateAnswer(NULL);
1267
1268   // Verify the session id is the same and the session version is
1269   // increased.
1270   EXPECT_EQ(session_id_orig, answer->session_id());
1271   EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1272             rtc::FromString<uint64>(answer->session_version()));
1273   SetLocalDescriptionWithoutError(answer);
1274
1275   ASSERT_EQ(2u, video_channel_->recv_streams().size());
1276   EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1277   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1278   ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1279   EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1280   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1281
1282   // Make sure we have no send streams.
1283   EXPECT_EQ(0u, video_channel_->send_streams().size());
1284   EXPECT_EQ(0u, voice_channel_->send_streams().size());
1285 }
1286
1287 TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
1288   Init(NULL);
1289   media_engine_->set_fail_create_channel(true);
1290
1291   SessionDescriptionInterface* offer = CreateOffer();
1292   ASSERT_TRUE(offer != NULL);
1293   // SetRemoteDescription and SetLocalDescription will take the ownership of
1294   // the offer.
1295   SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
1296   offer = CreateOffer();
1297   ASSERT_TRUE(offer != NULL);
1298   SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1299 }
1300
1301 //
1302 // Tests for creating/setting SDP under different SDES/DTLS polices:
1303 //
1304 // --DTLS off and SDES on
1305 // TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1306 //     set local/remote offer/answer with crypto --> success
1307 // TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1308 //     failure
1309 // TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1310 //     failure
1311 // TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1312 //     failure
1313 //
1314 // --DTLS on and SDES off
1315 // TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1316 //     set local/remote offer/answer with DTLS fingerprint --> success
1317 // TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1318 //     fingerprint --> failure
1319 // TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1320 //     --> failure
1321 // TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1322 //     --> failure
1323 //
1324 // --Encryption disabled: DTLS off and SDES off
1325 // TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1326 //     answer without SDES or DTLS --> success
1327 // TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1328 //     answer without SDES or DTLS --> success
1329 //
1330
1331 // Test that we return a failure when applying a remote/local offer that doesn't
1332 // have cryptos enabled when DTLS is off.
1333 TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
1334   Init(NULL);
1335   cricket::MediaSessionOptions options;
1336   options.has_video = true;
1337   JsepSessionDescription* offer = CreateRemoteOffer(
1338       options, cricket::SEC_DISABLED);
1339   ASSERT_TRUE(offer != NULL);
1340   VerifyNoCryptoParams(offer->description(), false);
1341   // SetRemoteDescription and SetLocalDescription will take the ownership of
1342   // the offer.
1343   SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
1344   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1345   ASSERT_TRUE(offer != NULL);
1346   SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
1347 }
1348
1349 // Test that we return a failure when applying a local answer that doesn't have
1350 // cryptos enabled when DTLS is off.
1351 TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
1352   Init(NULL);
1353   SessionDescriptionInterface* offer = NULL;
1354   SessionDescriptionInterface* answer = NULL;
1355   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1356   // SetRemoteDescription and SetLocalDescription will take the ownership of
1357   // the offer.
1358   SetRemoteDescriptionWithoutError(offer);
1359   SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
1360 }
1361
1362 // Test we will return fail when apply an remote answer that doesn't have
1363 // crypto enabled when DTLS is off.
1364 TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
1365   Init(NULL);
1366   SessionDescriptionInterface* offer = NULL;
1367   SessionDescriptionInterface* answer = NULL;
1368   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1369   // SetRemoteDescription and SetLocalDescription will take the ownership of
1370   // the offer.
1371   SetLocalDescriptionWithoutError(offer);
1372   SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
1373 }
1374
1375 // Test that we accept an offer with a DTLS fingerprint when DTLS is on
1376 // and that we return an answer with a DTLS fingerprint.
1377 TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
1378   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
1379   mediastream_signaling_.SendAudioVideoStream1();
1380   InitWithDtls();
1381   SetFactoryDtlsSrtp();
1382   cricket::MediaSessionOptions options;
1383   options.has_video = true;
1384   JsepSessionDescription* offer =
1385       CreateRemoteOffer(options, cricket::SEC_DISABLED);
1386   ASSERT_TRUE(offer != NULL);
1387   VerifyFingerprintStatus(offer->description(), true);
1388   VerifyNoCryptoParams(offer->description(), true);
1389
1390   // SetRemoteDescription will take the ownership of the offer.
1391   SetRemoteDescriptionWithoutError(offer);
1392
1393   // Verify that we get a crypto fingerprint in the answer.
1394   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1395   ASSERT_TRUE(answer != NULL);
1396   VerifyFingerprintStatus(answer->description(), true);
1397   // Check that we don't have an a=crypto line in the answer.
1398   VerifyNoCryptoParams(answer->description(), true);
1399
1400   // Now set the local description, which should work, even without a=crypto.
1401   SetLocalDescriptionWithoutError(answer);
1402 }
1403
1404 // Test that we set a local offer with a DTLS fingerprint when DTLS is on
1405 // and then we accept a remote answer with a DTLS fingerprint successfully.
1406 TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
1407   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
1408   mediastream_signaling_.SendAudioVideoStream1();
1409   InitWithDtls();
1410   SetFactoryDtlsSrtp();
1411
1412   // Verify that we get a crypto fingerprint in the answer.
1413   SessionDescriptionInterface* offer = CreateOffer();
1414   ASSERT_TRUE(offer != NULL);
1415   VerifyFingerprintStatus(offer->description(), true);
1416   // Check that we don't have an a=crypto line in the offer.
1417   VerifyNoCryptoParams(offer->description(), true);
1418
1419   // Now set the local description, which should work, even without a=crypto.
1420   SetLocalDescriptionWithoutError(offer);
1421
1422   cricket::MediaSessionOptions options;
1423   options.has_video = true;
1424   JsepSessionDescription* answer =
1425       CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1426   ASSERT_TRUE(answer != NULL);
1427   VerifyFingerprintStatus(answer->description(), true);
1428   VerifyNoCryptoParams(answer->description(), true);
1429
1430   // SetRemoteDescription will take the ownership of the answer.
1431   SetRemoteDescriptionWithoutError(answer);
1432 }
1433
1434 // Test that if we support DTLS and the other side didn't offer a fingerprint,
1435 // we will fail to set the remote description.
1436 TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
1437   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
1438   InitWithDtls();
1439   cricket::MediaSessionOptions options;
1440   options.has_video = true;
1441   options.bundle_enabled = true;
1442   JsepSessionDescription* offer = CreateRemoteOffer(
1443       options, cricket::SEC_REQUIRED);
1444   ASSERT_TRUE(offer != NULL);
1445   VerifyFingerprintStatus(offer->description(), false);
1446   VerifyCryptoParams(offer->description());
1447
1448   // SetRemoteDescription will take the ownership of the offer.
1449   SetRemoteDescriptionOfferExpectError(
1450       kSdpWithoutDtlsFingerprint, offer);
1451
1452   offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1453   // SetLocalDescription will take the ownership of the offer.
1454   SetLocalDescriptionOfferExpectError(
1455       kSdpWithoutDtlsFingerprint, offer);
1456 }
1457
1458 // Test that we return a failure when applying a local answer that doesn't have
1459 // a DTLS fingerprint when DTLS is required.
1460 TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
1461   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
1462   InitWithDtls();
1463   SessionDescriptionInterface* offer = NULL;
1464   SessionDescriptionInterface* answer = NULL;
1465   CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1466
1467   // SetRemoteDescription and SetLocalDescription will take the ownership of
1468   // the offer and answer.
1469   SetRemoteDescriptionWithoutError(offer);
1470   SetLocalDescriptionAnswerExpectError(
1471       kSdpWithoutDtlsFingerprint, answer);
1472 }
1473
1474 // Test that we return a failure when applying a remote answer that doesn't have
1475 // a DTLS fingerprint when DTLS is required.
1476 TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
1477   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
1478   InitWithDtls();
1479   SessionDescriptionInterface* offer = CreateOffer();
1480   cricket::MediaSessionOptions options;
1481   options.has_video = true;
1482   JsepSessionDescription* answer =
1483       CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
1484
1485   // SetRemoteDescription and SetLocalDescription will take the ownership of
1486   // the offer and answer.
1487   SetLocalDescriptionWithoutError(offer);
1488   SetRemoteDescriptionAnswerExpectError(
1489       kSdpWithoutDtlsFingerprint, answer);
1490 }
1491
1492 // Test that we create a local offer without SDES or DTLS and accept a remote
1493 // answer without SDES or DTLS when encryption is disabled.
1494 TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
1495   mediastream_signaling_.SendAudioVideoStream1();
1496   options_.disable_encryption = true;
1497   InitWithDtls();
1498
1499   // Verify that we get a crypto fingerprint in the answer.
1500   SessionDescriptionInterface* offer = CreateOffer();
1501   ASSERT_TRUE(offer != NULL);
1502   VerifyFingerprintStatus(offer->description(), false);
1503   // Check that we don't have an a=crypto line in the offer.
1504   VerifyNoCryptoParams(offer->description(), false);
1505
1506   // Now set the local description, which should work, even without a=crypto.
1507   SetLocalDescriptionWithoutError(offer);
1508
1509   cricket::MediaSessionOptions options;
1510   options.has_video = true;
1511   JsepSessionDescription* answer =
1512       CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1513   ASSERT_TRUE(answer != NULL);
1514   VerifyFingerprintStatus(answer->description(), false);
1515   VerifyNoCryptoParams(answer->description(), false);
1516
1517   // SetRemoteDescription will take the ownership of the answer.
1518   SetRemoteDescriptionWithoutError(answer);
1519 }
1520
1521 // Test that we create a local answer without SDES or DTLS and accept a remote
1522 // offer without SDES or DTLS when encryption is disabled.
1523 TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
1524   options_.disable_encryption = true;
1525   InitWithDtls();
1526
1527   cricket::MediaSessionOptions options;
1528   options.has_video = true;
1529   JsepSessionDescription* offer =
1530       CreateRemoteOffer(options, cricket::SEC_DISABLED);
1531   ASSERT_TRUE(offer != NULL);
1532   VerifyFingerprintStatus(offer->description(), false);
1533   VerifyNoCryptoParams(offer->description(), false);
1534
1535   // SetRemoteDescription will take the ownership of the offer.
1536   SetRemoteDescriptionWithoutError(offer);
1537
1538   // Verify that we get a crypto fingerprint in the answer.
1539   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1540   ASSERT_TRUE(answer != NULL);
1541   VerifyFingerprintStatus(answer->description(), false);
1542   // Check that we don't have an a=crypto line in the answer.
1543   VerifyNoCryptoParams(answer->description(), false);
1544
1545   // Now set the local description, which should work, even without a=crypto.
1546   SetLocalDescriptionWithoutError(answer);
1547 }
1548
1549 TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
1550   Init(NULL);
1551   mediastream_signaling_.SendNothing();
1552   // SetLocalDescription take ownership of offer.
1553   SessionDescriptionInterface* offer = CreateOffer();
1554   SetLocalDescriptionWithoutError(offer);
1555
1556   // SetLocalDescription take ownership of offer.
1557   SessionDescriptionInterface* offer2 = CreateOffer();
1558   SetLocalDescriptionWithoutError(offer2);
1559 }
1560
1561 TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
1562   Init(NULL);
1563   mediastream_signaling_.SendNothing();
1564   // SetLocalDescription take ownership of offer.
1565   SessionDescriptionInterface* offer = CreateOffer();
1566   SetRemoteDescriptionWithoutError(offer);
1567
1568   SessionDescriptionInterface* offer2 = CreateOffer();
1569   SetRemoteDescriptionWithoutError(offer2);
1570 }
1571
1572 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
1573   Init(NULL);
1574   mediastream_signaling_.SendNothing();
1575   SessionDescriptionInterface* offer = CreateOffer();
1576   SetLocalDescriptionWithoutError(offer);
1577   offer = CreateOffer();
1578   SetRemoteDescriptionOfferExpectError(
1579       "Called in wrong state: STATE_SENTINITIATE", offer);
1580 }
1581
1582 TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
1583   Init(NULL);
1584   mediastream_signaling_.SendNothing();
1585   SessionDescriptionInterface* offer = CreateOffer();
1586   SetRemoteDescriptionWithoutError(offer);
1587   offer = CreateOffer();
1588   SetLocalDescriptionOfferExpectError(
1589       "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
1590 }
1591
1592 TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
1593   Init(NULL);
1594   mediastream_signaling_.SendNothing();
1595   SessionDescriptionInterface* offer = CreateRemoteOffer();
1596   SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1597
1598   JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
1599       CreateAnswer(NULL));
1600   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1601   SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1602
1603   mediastream_signaling_.SendAudioVideoStream1();
1604   JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
1605       CreateAnswer(NULL));
1606   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1607
1608   SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1609
1610   mediastream_signaling_.SendAudioVideoStream2();
1611   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1612   SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1613 }
1614
1615 TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
1616   Init(NULL);
1617   mediastream_signaling_.SendNothing();
1618   SessionDescriptionInterface* offer = CreateOffer();
1619   SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1620
1621   JsepSessionDescription* pranswer =
1622       CreateRemoteAnswer(session_->local_description());
1623   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1624
1625   SetRemoteDescriptionExpectState(pranswer,
1626                                   BaseSession::STATE_RECEIVEDPRACCEPT);
1627
1628   mediastream_signaling_.SendAudioVideoStream1();
1629   JsepSessionDescription* pranswer2 =
1630       CreateRemoteAnswer(session_->local_description());
1631   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1632
1633   SetRemoteDescriptionExpectState(pranswer2,
1634                                   BaseSession::STATE_RECEIVEDPRACCEPT);
1635
1636   mediastream_signaling_.SendAudioVideoStream2();
1637   SessionDescriptionInterface* answer =
1638       CreateRemoteAnswer(session_->local_description());
1639   SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
1640 }
1641
1642 TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
1643   Init(NULL);
1644   mediastream_signaling_.SendNothing();
1645   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1646
1647   SessionDescriptionInterface* answer =
1648       CreateRemoteAnswer(offer.get());
1649   SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
1650                                        answer);
1651 }
1652
1653 TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
1654   Init(NULL);
1655   mediastream_signaling_.SendNothing();
1656   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1657
1658   SessionDescriptionInterface* answer =
1659       CreateRemoteAnswer(offer.get());
1660   SetRemoteDescriptionAnswerExpectError(
1661       "Called in wrong state: STATE_INIT", answer);
1662 }
1663
1664 TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
1665   Init(NULL);
1666   mediastream_signaling_.SendAudioVideoStream1();
1667
1668   cricket::Candidate candidate;
1669   candidate.set_component(1);
1670   JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
1671
1672   // Fail since we have not set a offer description.
1673   EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
1674
1675   SessionDescriptionInterface* offer = CreateOffer();
1676   SetLocalDescriptionWithoutError(offer);
1677   // Candidate should be allowed to add before remote description.
1678   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1679   candidate.set_component(2);
1680   JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
1681   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1682
1683   SessionDescriptionInterface* answer = CreateRemoteAnswer(
1684       session_->local_description());
1685   SetRemoteDescriptionWithoutError(answer);
1686
1687   // Verifying the candidates are copied properly from internal vector.
1688   const SessionDescriptionInterface* remote_desc =
1689       session_->remote_description();
1690   ASSERT_TRUE(remote_desc != NULL);
1691   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1692   const IceCandidateCollection* candidates =
1693       remote_desc->candidates(kMediaContentIndex0);
1694   ASSERT_EQ(2u, candidates->count());
1695   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1696   EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
1697   EXPECT_EQ(1, candidates->at(0)->candidate().component());
1698   EXPECT_EQ(2, candidates->at(1)->candidate().component());
1699
1700   // |ice_candidate3| is identical to |ice_candidate2|.  It can be added
1701   // successfully, but the total count of candidates will not increase.
1702   candidate.set_component(2);
1703   JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
1704   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
1705   ASSERT_EQ(2u, candidates->count());
1706
1707   JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
1708   EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
1709 }
1710
1711 // Test that a remote candidate is added to the remote session description and
1712 // that it is retained if the remote session description is changed.
1713 TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
1714   Init(NULL);
1715   cricket::Candidate candidate1;
1716   candidate1.set_component(1);
1717   JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
1718                                   candidate1);
1719   mediastream_signaling_.SendAudioVideoStream1();
1720   CreateAndSetRemoteOfferAndLocalAnswer();
1721
1722   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1723   const SessionDescriptionInterface* remote_desc =
1724       session_->remote_description();
1725   ASSERT_TRUE(remote_desc != NULL);
1726   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1727   const IceCandidateCollection* candidates =
1728       remote_desc->candidates(kMediaContentIndex0);
1729   ASSERT_EQ(1u, candidates->count());
1730   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1731
1732   // Update the RemoteSessionDescription with a new session description and
1733   // a candidate and check that the new remote session description contains both
1734   // candidates.
1735   SessionDescriptionInterface* offer = CreateRemoteOffer();
1736   cricket::Candidate candidate2;
1737   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
1738                                   candidate2);
1739   EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
1740   SetRemoteDescriptionWithoutError(offer);
1741
1742   remote_desc = session_->remote_description();
1743   ASSERT_TRUE(remote_desc != NULL);
1744   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1745   candidates = remote_desc->candidates(kMediaContentIndex0);
1746   ASSERT_EQ(2u, candidates->count());
1747   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1748   // Username and password have be updated with the TransportInfo of the
1749   // SessionDescription, won't be equal to the original one.
1750   candidate2.set_username(candidates->at(0)->candidate().username());
1751   candidate2.set_password(candidates->at(0)->candidate().password());
1752   EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
1753   EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
1754   // No need to verify the username and password.
1755   candidate1.set_username(candidates->at(1)->candidate().username());
1756   candidate1.set_password(candidates->at(1)->candidate().password());
1757   EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
1758
1759   // Test that the candidate is ignored if we can add the same candidate again.
1760   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1761 }
1762
1763 // Test that local candidates are added to the local session description and
1764 // that they are retained if the local session description is changed.
1765 TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
1766   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1767   Init(NULL);
1768   mediastream_signaling_.SendAudioVideoStream1();
1769   CreateAndSetRemoteOfferAndLocalAnswer();
1770
1771   const SessionDescriptionInterface* local_desc = session_->local_description();
1772   const IceCandidateCollection* candidates =
1773       local_desc->candidates(kMediaContentIndex0);
1774   ASSERT_TRUE(candidates != NULL);
1775   EXPECT_EQ(0u, candidates->count());
1776
1777   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1778
1779   local_desc = session_->local_description();
1780   candidates = local_desc->candidates(kMediaContentIndex0);
1781   ASSERT_TRUE(candidates != NULL);
1782   EXPECT_LT(0u, candidates->count());
1783   candidates = local_desc->candidates(1);
1784   ASSERT_TRUE(candidates != NULL);
1785   EXPECT_LT(0u, candidates->count());
1786
1787   // Update the session descriptions.
1788   mediastream_signaling_.SendAudioVideoStream1();
1789   CreateAndSetRemoteOfferAndLocalAnswer();
1790
1791   local_desc = session_->local_description();
1792   candidates = local_desc->candidates(kMediaContentIndex0);
1793   ASSERT_TRUE(candidates != NULL);
1794   EXPECT_LT(0u, candidates->count());
1795   candidates = local_desc->candidates(1);
1796   ASSERT_TRUE(candidates != NULL);
1797   EXPECT_LT(0u, candidates->count());
1798 }
1799
1800 // Test that we can set a remote session description with remote candidates.
1801 TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
1802   Init(NULL);
1803
1804   cricket::Candidate candidate1;
1805   candidate1.set_component(1);
1806   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
1807                                  candidate1);
1808   mediastream_signaling_.SendAudioVideoStream1();
1809   SessionDescriptionInterface* offer = CreateOffer();
1810
1811   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
1812   SetRemoteDescriptionWithoutError(offer);
1813
1814   const SessionDescriptionInterface* remote_desc =
1815       session_->remote_description();
1816   ASSERT_TRUE(remote_desc != NULL);
1817   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1818   const IceCandidateCollection* candidates =
1819       remote_desc->candidates(kMediaContentIndex0);
1820   ASSERT_EQ(1u, candidates->count());
1821   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1822
1823   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1824   SetLocalDescriptionWithoutError(answer);
1825 }
1826
1827 // Test that offers and answers contains ice candidates when Ice candidates have
1828 // been gathered.
1829 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
1830   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1831   Init(NULL);
1832   mediastream_signaling_.SendAudioVideoStream1();
1833   // Ice is started but candidates are not provided until SetLocalDescription
1834   // is called.
1835   EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1836   EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1837   CreateAndSetRemoteOfferAndLocalAnswer();
1838   // Wait until at least one local candidate has been collected.
1839   EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
1840                    kIceCandidatesTimeout);
1841   EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
1842                    kIceCandidatesTimeout);
1843
1844   rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
1845
1846   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
1847   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
1848   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
1849   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
1850
1851   SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
1852   SetRemoteDescriptionWithoutError(remote_offer);
1853   SessionDescriptionInterface* answer = CreateAnswer(NULL);
1854   ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
1855   EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
1856   ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
1857   EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
1858   SetLocalDescriptionWithoutError(answer);
1859 }
1860
1861 // Verifies TransportProxy and media channels are created with content names
1862 // present in the SessionDescription.
1863 TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
1864   Init(NULL);
1865   mediastream_signaling_.SendAudioVideoStream1();
1866   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1867
1868   // CreateOffer creates session description with the content names "audio" and
1869   // "video". Goal is to modify these content names and verify transport channel
1870   // proxy in the BaseSession, as proxies are created with the content names
1871   // present in SDP.
1872   std::string sdp;
1873   EXPECT_TRUE(offer->ToString(&sdp));
1874   const std::string kAudioMid = "a=mid:audio";
1875   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
1876   const std::string kVideoMid = "a=mid:video";
1877   const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
1878
1879   // Replacing |audio| with |audio_content_name|.
1880   rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
1881                              kAudioMidReplaceStr.c_str(),
1882                              kAudioMidReplaceStr.length(),
1883                              &sdp);
1884   // Replacing |video| with |video_content_name|.
1885   rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
1886                              kVideoMidReplaceStr.c_str(),
1887                              kVideoMidReplaceStr.length(),
1888                              &sdp);
1889
1890   SessionDescriptionInterface* modified_offer =
1891       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
1892
1893   SetRemoteDescriptionWithoutError(modified_offer);
1894
1895   SessionDescriptionInterface* answer =
1896       CreateAnswer(NULL);
1897   SetLocalDescriptionWithoutError(answer);
1898
1899   EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
1900   EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
1901   EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
1902   EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
1903 }
1904
1905 // Test that an offer contains the correct media content descriptions based on
1906 // the send streams when no constraints have been set.
1907 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
1908   Init(NULL);
1909   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1910
1911   ASSERT_TRUE(offer != NULL);
1912   const cricket::ContentInfo* content =
1913       cricket::GetFirstAudioContent(offer->description());
1914   EXPECT_TRUE(content != NULL);
1915   content = cricket::GetFirstVideoContent(offer->description());
1916   EXPECT_TRUE(content == NULL);
1917 }
1918
1919 // Test that an offer contains the correct media content descriptions based on
1920 // the send streams when no constraints have been set.
1921 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
1922   Init(NULL);
1923   // Test Audio only offer.
1924   mediastream_signaling_.UseOptionsAudioOnly();
1925   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1926
1927   const cricket::ContentInfo* content =
1928       cricket::GetFirstAudioContent(offer->description());
1929   EXPECT_TRUE(content != NULL);
1930   content = cricket::GetFirstVideoContent(offer->description());
1931   EXPECT_TRUE(content == NULL);
1932
1933   // Test Audio / Video offer.
1934   mediastream_signaling_.SendAudioVideoStream1();
1935   offer.reset(CreateOffer());
1936   content = cricket::GetFirstAudioContent(offer->description());
1937   EXPECT_TRUE(content != NULL);
1938   content = cricket::GetFirstVideoContent(offer->description());
1939   EXPECT_TRUE(content != NULL);
1940 }
1941
1942 // Test that an offer contains no media content descriptions if
1943 // kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
1944 TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
1945   Init(NULL);
1946   PeerConnectionInterface::RTCOfferAnswerOptions options;
1947   options.offer_to_receive_audio = 0;
1948   options.offer_to_receive_video = 0;
1949
1950   rtc::scoped_ptr<SessionDescriptionInterface> offer(
1951       CreateOffer(options));
1952
1953   ASSERT_TRUE(offer != NULL);
1954   const cricket::ContentInfo* content =
1955       cricket::GetFirstAudioContent(offer->description());
1956   EXPECT_TRUE(content == NULL);
1957   content = cricket::GetFirstVideoContent(offer->description());
1958   EXPECT_TRUE(content == NULL);
1959 }
1960
1961 // Test that an offer contains only audio media content descriptions if
1962 // kOfferToReceiveAudio constraints are set to true.
1963 TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
1964   Init(NULL);
1965   PeerConnectionInterface::RTCOfferAnswerOptions options;
1966   options.offer_to_receive_audio =
1967       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
1968
1969   rtc::scoped_ptr<SessionDescriptionInterface> offer(
1970         CreateOffer(options));
1971
1972   const cricket::ContentInfo* content =
1973       cricket::GetFirstAudioContent(offer->description());
1974   EXPECT_TRUE(content != NULL);
1975   content = cricket::GetFirstVideoContent(offer->description());
1976   EXPECT_TRUE(content == NULL);
1977 }
1978
1979 // Test that an offer contains audio and video media content descriptions if
1980 // kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
1981 TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
1982   Init(NULL);
1983   // Test Audio / Video offer.
1984   PeerConnectionInterface::RTCOfferAnswerOptions options;
1985   options.offer_to_receive_audio =
1986       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
1987   options.offer_to_receive_video =
1988       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
1989
1990   rtc::scoped_ptr<SessionDescriptionInterface> offer(
1991       CreateOffer(options));
1992
1993   const cricket::ContentInfo* content =
1994       cricket::GetFirstAudioContent(offer->description());
1995
1996   EXPECT_TRUE(content != NULL);
1997   content = cricket::GetFirstVideoContent(offer->description());
1998   EXPECT_TRUE(content != NULL);
1999
2000   // TODO(perkj): Should the direction be set to SEND_ONLY if
2001   // The constraints is set to not receive audio or video but a track is added?
2002 }
2003
2004 // Test that an answer can not be created if the last remote description is not
2005 // an offer.
2006 TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
2007   Init(NULL);
2008   SessionDescriptionInterface* offer = CreateOffer();
2009   SetLocalDescriptionWithoutError(offer);
2010   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2011   SetRemoteDescriptionWithoutError(answer);
2012   EXPECT_TRUE(CreateAnswer(NULL) == NULL);
2013 }
2014
2015 // Test that an answer contains the correct media content descriptions when no
2016 // constraints have been set.
2017 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
2018   Init(NULL);
2019   // Create a remote offer with audio and video content.
2020   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2021   SetRemoteDescriptionWithoutError(offer.release());
2022   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2023       CreateAnswer(NULL));
2024   const cricket::ContentInfo* content =
2025       cricket::GetFirstAudioContent(answer->description());
2026   ASSERT_TRUE(content != NULL);
2027   EXPECT_FALSE(content->rejected);
2028
2029   content = cricket::GetFirstVideoContent(answer->description());
2030   ASSERT_TRUE(content != NULL);
2031   EXPECT_FALSE(content->rejected);
2032 }
2033
2034 // Test that an answer contains the correct media content descriptions when no
2035 // constraints have been set and the offer only contain audio.
2036 TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
2037   Init(NULL);
2038   // Create a remote offer with audio only.
2039   cricket::MediaSessionOptions options;
2040   options.has_audio = true;
2041   options.has_video = false;
2042   rtc::scoped_ptr<JsepSessionDescription> offer(
2043       CreateRemoteOffer(options));
2044   ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2045   ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2046
2047   SetRemoteDescriptionWithoutError(offer.release());
2048   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2049       CreateAnswer(NULL));
2050   const cricket::ContentInfo* content =
2051       cricket::GetFirstAudioContent(answer->description());
2052   ASSERT_TRUE(content != NULL);
2053   EXPECT_FALSE(content->rejected);
2054
2055   EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2056 }
2057
2058 // Test that an answer contains the correct media content descriptions when no
2059 // constraints have been set.
2060 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
2061   Init(NULL);
2062   // Create a remote offer with audio and video content.
2063   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2064   SetRemoteDescriptionWithoutError(offer.release());
2065   // Test with a stream with tracks.
2066   mediastream_signaling_.SendAudioVideoStream1();
2067   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2068       CreateAnswer(NULL));
2069   const cricket::ContentInfo* content =
2070       cricket::GetFirstAudioContent(answer->description());
2071   ASSERT_TRUE(content != NULL);
2072   EXPECT_FALSE(content->rejected);
2073
2074   content = cricket::GetFirstVideoContent(answer->description());
2075   ASSERT_TRUE(content != NULL);
2076   EXPECT_FALSE(content->rejected);
2077 }
2078
2079 // Test that an answer contains the correct media content descriptions when
2080 // constraints have been set but no stream is sent.
2081 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
2082   Init(NULL);
2083   // Create a remote offer with audio and video content.
2084   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2085   SetRemoteDescriptionWithoutError(offer.release());
2086
2087   webrtc::FakeConstraints constraints_no_receive;
2088   constraints_no_receive.SetMandatoryReceiveAudio(false);
2089   constraints_no_receive.SetMandatoryReceiveVideo(false);
2090
2091   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2092       CreateAnswer(&constraints_no_receive));
2093   const cricket::ContentInfo* content =
2094       cricket::GetFirstAudioContent(answer->description());
2095   ASSERT_TRUE(content != NULL);
2096   EXPECT_TRUE(content->rejected);
2097
2098   content = cricket::GetFirstVideoContent(answer->description());
2099   ASSERT_TRUE(content != NULL);
2100   EXPECT_TRUE(content->rejected);
2101 }
2102
2103 // Test that an answer contains the correct media content descriptions when
2104 // constraints have been set and streams are sent.
2105 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
2106   Init(NULL);
2107   // Create a remote offer with audio and video content.
2108   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2109   SetRemoteDescriptionWithoutError(offer.release());
2110
2111   webrtc::FakeConstraints constraints_no_receive;
2112   constraints_no_receive.SetMandatoryReceiveAudio(false);
2113   constraints_no_receive.SetMandatoryReceiveVideo(false);
2114
2115   // Test with a stream with tracks.
2116   mediastream_signaling_.SendAudioVideoStream1();
2117   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2118       CreateAnswer(&constraints_no_receive));
2119
2120   // TODO(perkj): Should the direction be set to SEND_ONLY?
2121   const cricket::ContentInfo* content =
2122       cricket::GetFirstAudioContent(answer->description());
2123   ASSERT_TRUE(content != NULL);
2124   EXPECT_FALSE(content->rejected);
2125
2126   // TODO(perkj): Should the direction be set to SEND_ONLY?
2127   content = cricket::GetFirstVideoContent(answer->description());
2128   ASSERT_TRUE(content != NULL);
2129   EXPECT_FALSE(content->rejected);
2130 }
2131
2132 TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2133   AddCNCodecs();
2134   Init(NULL);
2135   PeerConnectionInterface::RTCOfferAnswerOptions options;
2136   options.offer_to_receive_audio =
2137       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2138   options.voice_activity_detection = false;
2139
2140   rtc::scoped_ptr<SessionDescriptionInterface> offer(
2141       CreateOffer(options));
2142
2143   const cricket::ContentInfo* content =
2144       cricket::GetFirstAudioContent(offer->description());
2145   EXPECT_TRUE(content != NULL);
2146   EXPECT_TRUE(VerifyNoCNCodecs(content));
2147 }
2148
2149 TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2150   AddCNCodecs();
2151   Init(NULL);
2152   // Create a remote offer with audio and video content.
2153   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2154   SetRemoteDescriptionWithoutError(offer.release());
2155
2156   webrtc::FakeConstraints constraints;
2157   constraints.SetOptionalVAD(false);
2158   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2159       CreateAnswer(&constraints));
2160   const cricket::ContentInfo* content =
2161       cricket::GetFirstAudioContent(answer->description());
2162   ASSERT_TRUE(content != NULL);
2163   EXPECT_TRUE(VerifyNoCNCodecs(content));
2164 }
2165
2166 // This test verifies the call setup when remote answer with audio only and
2167 // later updates with video.
2168 TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
2169   Init(NULL);
2170   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2171   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2172
2173   mediastream_signaling_.SendAudioVideoStream1();
2174   SessionDescriptionInterface* offer = CreateOffer();
2175
2176   cricket::MediaSessionOptions options;
2177   options.has_video = false;
2178   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2179
2180   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2181   // and answer;
2182   SetLocalDescriptionWithoutError(offer);
2183   SetRemoteDescriptionWithoutError(answer);
2184
2185   video_channel_ = media_engine_->GetVideoChannel(0);
2186   voice_channel_ = media_engine_->GetVoiceChannel(0);
2187
2188   ASSERT_TRUE(video_channel_ == NULL);
2189
2190   ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2191   ASSERT_EQ(1u, voice_channel_->send_streams().size());
2192   EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2193
2194   // Let the remote end update the session descriptions, with Audio and Video.
2195   mediastream_signaling_.SendAudioVideoStream2();
2196   CreateAndSetRemoteOfferAndLocalAnswer();
2197
2198   video_channel_ = media_engine_->GetVideoChannel(0);
2199   voice_channel_ = media_engine_->GetVoiceChannel(0);
2200
2201   ASSERT_TRUE(video_channel_ != NULL);
2202   ASSERT_TRUE(voice_channel_ != NULL);
2203
2204   ASSERT_EQ(1u, video_channel_->recv_streams().size());
2205   ASSERT_EQ(1u, video_channel_->send_streams().size());
2206   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2207   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2208   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2209   ASSERT_EQ(1u, voice_channel_->send_streams().size());
2210   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2211   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2212
2213   // Change session back to audio only.
2214   mediastream_signaling_.UseOptionsAudioOnly();
2215   CreateAndSetRemoteOfferAndLocalAnswer();
2216
2217   EXPECT_EQ(0u, video_channel_->recv_streams().size());
2218   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2219   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2220   ASSERT_EQ(1u, voice_channel_->send_streams().size());
2221   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2222 }
2223
2224 // This test verifies the call setup when remote answer with video only and
2225 // later updates with audio.
2226 TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
2227   Init(NULL);
2228   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2229   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2230   mediastream_signaling_.SendAudioVideoStream1();
2231   SessionDescriptionInterface* offer = CreateOffer();
2232
2233   cricket::MediaSessionOptions options;
2234   options.has_audio = false;
2235   options.has_video = true;
2236   SessionDescriptionInterface* answer = CreateRemoteAnswer(
2237       offer, options, cricket::SEC_ENABLED);
2238
2239   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2240   // and answer.
2241   SetLocalDescriptionWithoutError(offer);
2242   SetRemoteDescriptionWithoutError(answer);
2243
2244   video_channel_ = media_engine_->GetVideoChannel(0);
2245   voice_channel_ = media_engine_->GetVoiceChannel(0);
2246
2247   ASSERT_TRUE(voice_channel_ == NULL);
2248   ASSERT_TRUE(video_channel_ != NULL);
2249
2250   EXPECT_EQ(0u, video_channel_->recv_streams().size());
2251   ASSERT_EQ(1u, video_channel_->send_streams().size());
2252   EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2253
2254   // Update the session descriptions, with Audio and Video.
2255   mediastream_signaling_.SendAudioVideoStream2();
2256   CreateAndSetRemoteOfferAndLocalAnswer();
2257
2258   voice_channel_ = media_engine_->GetVoiceChannel(0);
2259   ASSERT_TRUE(voice_channel_ != NULL);
2260
2261   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2262   ASSERT_EQ(1u, voice_channel_->send_streams().size());
2263   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2264   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2265
2266   // Change session back to video only.
2267   mediastream_signaling_.UseOptionsVideoOnly();
2268   CreateAndSetRemoteOfferAndLocalAnswer();
2269
2270   video_channel_ = media_engine_->GetVideoChannel(0);
2271   voice_channel_ = media_engine_->GetVoiceChannel(0);
2272
2273   ASSERT_EQ(1u, video_channel_->recv_streams().size());
2274   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2275   ASSERT_EQ(1u, video_channel_->send_streams().size());
2276   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2277 }
2278
2279 TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
2280   Init(NULL);
2281   mediastream_signaling_.SendAudioVideoStream1();
2282   scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2283   VerifyCryptoParams(offer->description());
2284   SetRemoteDescriptionWithoutError(offer.release());
2285   scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
2286   VerifyCryptoParams(answer->description());
2287 }
2288
2289 TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
2290   options_.disable_encryption = true;
2291   Init(NULL);
2292   mediastream_signaling_.SendAudioVideoStream1();
2293   scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2294   VerifyNoCryptoParams(offer->description(), false);
2295 }
2296
2297 TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
2298   Init(NULL);
2299   VerifyAnswerFromNonCryptoOffer();
2300 }
2301
2302 TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
2303   Init(NULL);
2304   VerifyAnswerFromCryptoOffer();
2305 }
2306
2307 // This test verifies that setLocalDescription fails if
2308 // no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2309 TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
2310   Init(NULL);
2311   mediastream_signaling_.SendAudioVideoStream1();
2312   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2313
2314   std::string sdp;
2315   RemoveIceUfragPwdLines(offer.get(), &sdp);
2316   SessionDescriptionInterface* modified_offer =
2317     CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2318   SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
2319 }
2320
2321 // This test verifies that setRemoteDescription fails if
2322 // no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2323 TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
2324   Init(NULL);
2325   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2326   std::string sdp;
2327   RemoveIceUfragPwdLines(offer.get(), &sdp);
2328   SessionDescriptionInterface* modified_offer =
2329     CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2330   SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
2331 }
2332
2333 // This test verifies that setLocalDescription fails if local offer has
2334 // too short ice ufrag and pwd strings.
2335 TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
2336   Init(NULL);
2337   tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
2338   mediastream_signaling_.SendAudioVideoStream1();
2339   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2340
2341   std::string sdp;
2342   // Modifying ice ufrag and pwd in local offer with strings smaller than the
2343   // recommended values of 4 and 22 bytes respectively.
2344   ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2345   SessionDescriptionInterface* modified_offer =
2346       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2347   std::string error;
2348   EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2349
2350   // Test with string greater than 256.
2351   sdp.clear();
2352   ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2353                          &sdp);
2354   modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2355                                             NULL);
2356   EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2357 }
2358
2359 // This test verifies that setRemoteDescription fails if remote offer has
2360 // too short ice ufrag and pwd strings.
2361 TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
2362   Init(NULL);
2363   tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
2364   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2365   std::string sdp;
2366   // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2367   // recommended values of 4 and 22 bytes respectively.
2368   ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2369   SessionDescriptionInterface* modified_offer =
2370      CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2371   std::string error;
2372   EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2373
2374   sdp.clear();
2375   ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2376                          &sdp);
2377   modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2378                                             NULL);
2379   EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2380 }
2381
2382 TEST_F(WebRtcSessionTest, VerifyBundleFlagInPA) {
2383   // This test verifies BUNDLE flag in PortAllocator, if BUNDLE information in
2384   // local description is removed by the application, BUNDLE flag should be
2385   // disabled in PortAllocator. By default BUNDLE is enabled in the WebRtc.
2386   Init(NULL);
2387   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
2388       allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2389   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2390
2391   cricket::SessionDescription* offer_copy =
2392       offer->description()->Copy();
2393   offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2394   JsepSessionDescription* modified_offer =
2395       new JsepSessionDescription(JsepSessionDescription::kOffer);
2396   modified_offer->Initialize(offer_copy, "1", "1");
2397
2398   SetLocalDescriptionWithoutError(modified_offer);
2399   EXPECT_FALSE(allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2400 }
2401
2402 TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
2403   Init(NULL);
2404   mediastream_signaling_.SendAudioVideoStream1();
2405   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
2406       allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2407
2408   PeerConnectionInterface::RTCOfferAnswerOptions options;
2409   options.use_rtp_mux = true;
2410
2411   SessionDescriptionInterface* offer = CreateOffer(options);
2412
2413   SetLocalDescriptionWithoutError(offer);
2414   mediastream_signaling_.SendAudioVideoStream2();
2415   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2416       CreateRemoteAnswer(session_->local_description()));
2417   cricket::SessionDescription* answer_copy = answer->description()->Copy();
2418   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2419   JsepSessionDescription* modified_answer =
2420       new JsepSessionDescription(JsepSessionDescription::kAnswer);
2421   modified_answer->Initialize(answer_copy, "1", "1");
2422   SetRemoteDescriptionWithoutError(modified_answer);
2423   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
2424       allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2425
2426   video_channel_ = media_engine_->GetVideoChannel(0);
2427   voice_channel_ = media_engine_->GetVoiceChannel(0);
2428
2429   ASSERT_EQ(1u, video_channel_->recv_streams().size());
2430   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
2431
2432   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2433   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
2434
2435   ASSERT_EQ(1u, video_channel_->send_streams().size());
2436   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
2437   ASSERT_EQ(1u, voice_channel_->send_streams().size());
2438   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
2439 }
2440
2441 // This test verifies that SetLocalDescription and SetRemoteDescription fails
2442 // if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
2443 TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
2444   WebRtcSessionTest::Init(NULL);
2445   mediastream_signaling_.SendAudioVideoStream1();
2446   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
2447       allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2448
2449   PeerConnectionInterface::RTCOfferAnswerOptions options;
2450   options.use_rtp_mux = true;
2451
2452   SessionDescriptionInterface* offer = CreateOffer(options);
2453   std::string offer_str;
2454   offer->ToString(&offer_str);
2455   // Disable rtcp-mux
2456   const std::string rtcp_mux = "rtcp-mux";
2457   const std::string xrtcp_mux = "xrtcp-mux";
2458   rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
2459                              xrtcp_mux.c_str(), xrtcp_mux.length(),
2460                              &offer_str);
2461   JsepSessionDescription *local_offer =
2462       new JsepSessionDescription(JsepSessionDescription::kOffer);
2463   EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
2464   SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
2465   JsepSessionDescription *remote_offer =
2466       new JsepSessionDescription(JsepSessionDescription::kOffer);
2467   EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
2468   SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
2469   // Trying unmodified SDP.
2470   SetLocalDescriptionWithoutError(offer);
2471 }
2472
2473 TEST_F(WebRtcSessionTest, SetAudioPlayout) {
2474   Init(NULL);
2475   mediastream_signaling_.SendAudioVideoStream1();
2476   CreateAndSetRemoteOfferAndLocalAnswer();
2477   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2478   ASSERT_TRUE(channel != NULL);
2479   ASSERT_EQ(1u, channel->recv_streams().size());
2480   uint32 receive_ssrc  = channel->recv_streams()[0].first_ssrc();
2481   double left_vol, right_vol;
2482   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2483   EXPECT_EQ(1, left_vol);
2484   EXPECT_EQ(1, right_vol);
2485   rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2486   session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
2487   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2488   EXPECT_EQ(0, left_vol);
2489   EXPECT_EQ(0, right_vol);
2490   EXPECT_EQ(0, renderer->channel_id());
2491   session_->SetAudioPlayout(receive_ssrc, true, NULL);
2492   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2493   EXPECT_EQ(1, left_vol);
2494   EXPECT_EQ(1, right_vol);
2495   EXPECT_EQ(-1, renderer->channel_id());
2496 }
2497
2498 TEST_F(WebRtcSessionTest, SetAudioSend) {
2499   Init(NULL);
2500   mediastream_signaling_.SendAudioVideoStream1();
2501   CreateAndSetRemoteOfferAndLocalAnswer();
2502   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2503   ASSERT_TRUE(channel != NULL);
2504   ASSERT_EQ(1u, channel->send_streams().size());
2505   uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
2506   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2507
2508   cricket::AudioOptions options;
2509   options.echo_cancellation.Set(true);
2510
2511   rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2512   session_->SetAudioSend(send_ssrc, false, options, renderer.get());
2513   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2514   EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
2515   EXPECT_EQ(0, renderer->channel_id());
2516   EXPECT_TRUE(renderer->sink() != NULL);
2517
2518   // This will trigger SetSink(NULL) to the |renderer|.
2519   session_->SetAudioSend(send_ssrc, true, options, NULL);
2520   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2521   bool value;
2522   EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
2523   EXPECT_TRUE(value);
2524   EXPECT_EQ(-1, renderer->channel_id());
2525   EXPECT_TRUE(renderer->sink() == NULL);
2526 }
2527
2528 TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
2529   Init(NULL);
2530   mediastream_signaling_.SendAudioVideoStream1();
2531   CreateAndSetRemoteOfferAndLocalAnswer();
2532   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2533   ASSERT_TRUE(channel != NULL);
2534   ASSERT_EQ(1u, channel->send_streams().size());
2535   uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
2536
2537   rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2538   cricket::AudioOptions options;
2539   session_->SetAudioSend(send_ssrc, true, options, renderer.get());
2540   EXPECT_TRUE(renderer->sink() != NULL);
2541
2542   // Delete the |renderer| and it will trigger OnClose() to the sink, and this
2543   // will invalidate the |renderer_| pointer in the sink and prevent getting a
2544   // SetSink(NULL) callback afterwards.
2545   renderer.reset();
2546
2547   // This will trigger SetSink(NULL) if no OnClose() callback.
2548   session_->SetAudioSend(send_ssrc, true, options, NULL);
2549 }
2550
2551 TEST_F(WebRtcSessionTest, SetVideoPlayout) {
2552   Init(NULL);
2553   mediastream_signaling_.SendAudioVideoStream1();
2554   CreateAndSetRemoteOfferAndLocalAnswer();
2555   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2556   ASSERT_TRUE(channel != NULL);
2557   ASSERT_LT(0u, channel->renderers().size());
2558   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2559   ASSERT_EQ(1u, channel->recv_streams().size());
2560   uint32 receive_ssrc  = channel->recv_streams()[0].first_ssrc();
2561   cricket::FakeVideoRenderer renderer;
2562   session_->SetVideoPlayout(receive_ssrc, true, &renderer);
2563   EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
2564   session_->SetVideoPlayout(receive_ssrc, false, &renderer);
2565   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2566 }
2567
2568 TEST_F(WebRtcSessionTest, SetVideoSend) {
2569   Init(NULL);
2570   mediastream_signaling_.SendAudioVideoStream1();
2571   CreateAndSetRemoteOfferAndLocalAnswer();
2572   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2573   ASSERT_TRUE(channel != NULL);
2574   ASSERT_EQ(1u, channel->send_streams().size());
2575   uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
2576   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2577   cricket::VideoOptions* options = NULL;
2578   session_->SetVideoSend(send_ssrc, false, options);
2579   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2580   session_->SetVideoSend(send_ssrc, true, options);
2581   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2582 }
2583
2584 TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
2585   TestCanInsertDtmf(false);
2586 }
2587
2588 TEST_F(WebRtcSessionTest, CanInsertDtmf) {
2589   TestCanInsertDtmf(true);
2590 }
2591
2592 TEST_F(WebRtcSessionTest, InsertDtmf) {
2593   // Setup
2594   Init(NULL);
2595   mediastream_signaling_.SendAudioVideoStream1();
2596   CreateAndSetRemoteOfferAndLocalAnswer();
2597   FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2598   EXPECT_EQ(0U, channel->dtmf_info_queue().size());
2599
2600   // Insert DTMF
2601   const int expected_flags = DF_SEND;
2602   const int expected_duration = 90;
2603   session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
2604   session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
2605   session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
2606
2607   // Verify
2608   ASSERT_EQ(3U, channel->dtmf_info_queue().size());
2609   const uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
2610   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
2611                               expected_duration, expected_flags));
2612   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
2613                               expected_duration, expected_flags));
2614   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
2615                               expected_duration, expected_flags));
2616 }
2617
2618 // This test verifies the |initiator| flag when session initiates the call.
2619 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
2620   Init(NULL);
2621   EXPECT_FALSE(session_->initiator());
2622   SessionDescriptionInterface* offer = CreateOffer();
2623   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2624   SetLocalDescriptionWithoutError(offer);
2625   EXPECT_TRUE(session_->initiator());
2626   SetRemoteDescriptionWithoutError(answer);
2627   EXPECT_TRUE(session_->initiator());
2628 }
2629
2630 // This test verifies the |initiator| flag when session receives the call.
2631 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
2632   Init(NULL);
2633   EXPECT_FALSE(session_->initiator());
2634   SessionDescriptionInterface* offer = CreateRemoteOffer();
2635   SetRemoteDescriptionWithoutError(offer);
2636   SessionDescriptionInterface* answer = CreateAnswer(NULL);
2637
2638   EXPECT_FALSE(session_->initiator());
2639   SetLocalDescriptionWithoutError(answer);
2640   EXPECT_FALSE(session_->initiator());
2641 }
2642
2643 // This test verifies the ice protocol type at initiator of the call
2644 // if |a=ice-options:google-ice| is present in answer.
2645 TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
2646   Init(NULL);
2647   mediastream_signaling_.SendAudioVideoStream1();
2648   SessionDescriptionInterface* offer = CreateOffer();
2649   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2650       CreateRemoteAnswer(offer));
2651   SetLocalDescriptionWithoutError(offer);
2652   std::string sdp;
2653   EXPECT_TRUE(answer->ToString(&sdp));
2654   // Adding ice-options to the session level.
2655   InjectAfter("t=0 0\r\n",
2656               "a=ice-options:google-ice\r\n",
2657               &sdp);
2658   SessionDescriptionInterface* answer_with_gice =
2659       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2660   SetRemoteDescriptionWithoutError(answer_with_gice);
2661   VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
2662   VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
2663 }
2664
2665 // This test verifies the ice protocol type at initiator of the call
2666 // if ICE RFC5245 is supported in answer.
2667 TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
2668   Init(NULL);
2669   mediastream_signaling_.SendAudioVideoStream1();
2670   SessionDescriptionInterface* offer = CreateOffer();
2671   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2672   SetLocalDescriptionWithoutError(offer);
2673
2674   SetRemoteDescriptionWithoutError(answer);
2675   VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
2676   VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
2677 }
2678
2679 // This test verifies the ice protocol type at receiver side of the call if
2680 // receiver decides to use google-ice.
2681 TEST_F(WebRtcSessionTest, TestReceiverGIceInOffer) {
2682   Init(NULL);
2683   mediastream_signaling_.SendAudioVideoStream1();
2684   SessionDescriptionInterface* offer = CreateOffer();
2685   SetRemoteDescriptionWithoutError(offer);
2686   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2687       CreateAnswer(NULL));
2688   std::string sdp;
2689   EXPECT_TRUE(answer->ToString(&sdp));
2690   // Adding ice-options to the session level.
2691   InjectAfter("t=0 0\r\n",
2692               "a=ice-options:google-ice\r\n",
2693               &sdp);
2694   SessionDescriptionInterface* answer_with_gice =
2695       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2696   SetLocalDescriptionWithoutError(answer_with_gice);
2697   VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
2698   VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
2699 }
2700
2701 // This test verifies the ice protocol type at receiver side of the call if
2702 // receiver decides to use ice RFC 5245.
2703 TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
2704   Init(NULL);
2705   mediastream_signaling_.SendAudioVideoStream1();
2706   SessionDescriptionInterface* offer = CreateOffer();
2707   SetRemoteDescriptionWithoutError(offer);
2708   SessionDescriptionInterface* answer = CreateAnswer(NULL);
2709   SetLocalDescriptionWithoutError(answer);
2710   VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
2711   VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
2712 }
2713
2714 // This test verifies the session state when ICE RFC5245 in offer and
2715 // ICE google-ice in answer.
2716 TEST_F(WebRtcSessionTest, TestIceOfferGIceOnlyAnswer) {
2717   Init(NULL);
2718   mediastream_signaling_.SendAudioVideoStream1();
2719   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2720
2721   std::string offer_str;
2722   offer->ToString(&offer_str);
2723   // Disable google-ice
2724   const std::string gice_option = "google-ice";
2725   const std::string xgoogle_xice = "xgoogle-xice";
2726   rtc::replace_substrs(gice_option.c_str(), gice_option.length(),
2727                              xgoogle_xice.c_str(), xgoogle_xice.length(),
2728                              &offer_str);
2729   JsepSessionDescription *ice_only_offer =
2730       new JsepSessionDescription(JsepSessionDescription::kOffer);
2731   EXPECT_TRUE((ice_only_offer)->Initialize(offer_str, NULL));
2732   SetLocalDescriptionWithoutError(ice_only_offer);
2733   std::string original_offer_sdp;
2734   EXPECT_TRUE(offer->ToString(&original_offer_sdp));
2735   SessionDescriptionInterface* pranswer_with_gice =
2736       CreateSessionDescription(JsepSessionDescription::kPrAnswer,
2737                                original_offer_sdp, NULL);
2738   SetRemoteDescriptionPranswerExpectError(kPushDownTDFailed,
2739                                           pranswer_with_gice);
2740   SessionDescriptionInterface* answer_with_gice =
2741       CreateSessionDescription(JsepSessionDescription::kAnswer,
2742                                original_offer_sdp, NULL);
2743   SetRemoteDescriptionAnswerExpectError(kPushDownTDFailed,
2744                                         answer_with_gice);
2745 }
2746
2747 // Verifing local offer and remote answer have matching m-lines as per RFC 3264.
2748 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
2749   Init(NULL);
2750   mediastream_signaling_.SendAudioVideoStream1();
2751   SessionDescriptionInterface* offer = CreateOffer();
2752   SetLocalDescriptionWithoutError(offer);
2753   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2754       CreateRemoteAnswer(session_->local_description()));
2755
2756   cricket::SessionDescription* answer_copy = answer->description()->Copy();
2757   answer_copy->RemoveContentByName("video");
2758   JsepSessionDescription* modified_answer =
2759       new JsepSessionDescription(JsepSessionDescription::kAnswer);
2760
2761   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
2762                                           answer->session_id(),
2763                                           answer->session_version()));
2764   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
2765
2766   // Different content names.
2767   std::string sdp;
2768   EXPECT_TRUE(answer->ToString(&sdp));
2769   const std::string kAudioMid = "a=mid:audio";
2770   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2771   rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
2772                              kAudioMidReplaceStr.c_str(),
2773                              kAudioMidReplaceStr.length(),
2774                              &sdp);
2775   SessionDescriptionInterface* modified_answer1 =
2776       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2777   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
2778
2779   // Different media types.
2780   EXPECT_TRUE(answer->ToString(&sdp));
2781   const std::string kAudioMline = "m=audio";
2782   const std::string kAudioMlineReplaceStr = "m=video";
2783   rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
2784                              kAudioMlineReplaceStr.c_str(),
2785                              kAudioMlineReplaceStr.length(),
2786                              &sdp);
2787   SessionDescriptionInterface* modified_answer2 =
2788       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2789   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
2790
2791   SetRemoteDescriptionWithoutError(answer.release());
2792 }
2793
2794 // Verifying remote offer and local answer have matching m-lines as per
2795 // RFC 3264.
2796 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
2797   Init(NULL);
2798   mediastream_signaling_.SendAudioVideoStream1();
2799   SessionDescriptionInterface* offer = CreateRemoteOffer();
2800   SetRemoteDescriptionWithoutError(offer);
2801   SessionDescriptionInterface* answer = CreateAnswer(NULL);
2802
2803   cricket::SessionDescription* answer_copy = answer->description()->Copy();
2804   answer_copy->RemoveContentByName("video");
2805   JsepSessionDescription* modified_answer =
2806       new JsepSessionDescription(JsepSessionDescription::kAnswer);
2807
2808   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
2809                                           answer->session_id(),
2810                                           answer->session_version()));
2811   SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
2812   SetLocalDescriptionWithoutError(answer);
2813 }
2814
2815 // This test verifies that WebRtcSession does not start candidate allocation
2816 // before SetLocalDescription is called.
2817 TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
2818   Init(NULL);
2819   mediastream_signaling_.SendAudioVideoStream1();
2820   SessionDescriptionInterface* offer = CreateRemoteOffer();
2821   cricket::Candidate candidate;
2822   candidate.set_component(1);
2823   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2824                                  candidate);
2825   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2826   cricket::Candidate candidate1;
2827   candidate1.set_component(1);
2828   JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
2829                                   candidate1);
2830   EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
2831   SetRemoteDescriptionWithoutError(offer);
2832   ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
2833   ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
2834
2835   // Pump for 1 second and verify that no candidates are generated.
2836   rtc::Thread::Current()->ProcessMessages(1000);
2837   EXPECT_TRUE(observer_.mline_0_candidates_.empty());
2838   EXPECT_TRUE(observer_.mline_1_candidates_.empty());
2839
2840   SessionDescriptionInterface* answer = CreateAnswer(NULL);
2841   SetLocalDescriptionWithoutError(answer);
2842   EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
2843   EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
2844   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2845 }
2846
2847 // This test verifies that crypto parameter is updated in local session
2848 // description as per security policy set in MediaSessionDescriptionFactory.
2849 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
2850   Init(NULL);
2851   mediastream_signaling_.SendAudioVideoStream1();
2852   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2853
2854   // Making sure SetLocalDescription correctly sets crypto value in
2855   // SessionDescription object after de-serialization of sdp string. The value
2856   // will be set as per MediaSessionDescriptionFactory.
2857   std::string offer_str;
2858   offer->ToString(&offer_str);
2859   SessionDescriptionInterface* jsep_offer_str =
2860       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
2861   SetLocalDescriptionWithoutError(jsep_offer_str);
2862   EXPECT_TRUE(session_->voice_channel()->secure_required());
2863   EXPECT_TRUE(session_->video_channel()->secure_required());
2864 }
2865
2866 // This test verifies the crypto parameter when security is disabled.
2867 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
2868   options_.disable_encryption = true;
2869   Init(NULL);
2870   mediastream_signaling_.SendAudioVideoStream1();
2871   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2872
2873   // Making sure SetLocalDescription correctly sets crypto value in
2874   // SessionDescription object after de-serialization of sdp string. The value
2875   // will be set as per MediaSessionDescriptionFactory.
2876   std::string offer_str;
2877   offer->ToString(&offer_str);
2878   SessionDescriptionInterface *jsep_offer_str =
2879       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
2880   SetLocalDescriptionWithoutError(jsep_offer_str);
2881   EXPECT_FALSE(session_->voice_channel()->secure_required());
2882   EXPECT_FALSE(session_->video_channel()->secure_required());
2883 }
2884
2885 // This test verifies that an answer contains new ufrag and password if an offer
2886 // with new ufrag and password is received.
2887 TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
2888   Init(NULL);
2889   cricket::MediaSessionOptions options;
2890   options.has_audio = true;
2891   options.has_video = true;
2892   rtc::scoped_ptr<JsepSessionDescription> offer(
2893       CreateRemoteOffer(options));
2894   SetRemoteDescriptionWithoutError(offer.release());
2895
2896   mediastream_signaling_.SendAudioVideoStream1();
2897   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2898       CreateAnswer(NULL));
2899   SetLocalDescriptionWithoutError(answer.release());
2900
2901   // Receive an offer with new ufrag and password.
2902   options.transport_options.ice_restart = true;
2903   rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
2904       CreateRemoteOffer(options, session_->remote_description()));
2905   SetRemoteDescriptionWithoutError(updated_offer1.release());
2906
2907   rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
2908       CreateAnswer(NULL));
2909
2910   CompareIceUfragAndPassword(updated_answer1->description(),
2911                              session_->local_description()->description(),
2912                              false);
2913
2914   SetLocalDescriptionWithoutError(updated_answer1.release());
2915 }
2916
2917 // This test verifies that an answer contains old ufrag and password if an offer
2918 // with old ufrag and password is received.
2919 TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
2920   Init(NULL);
2921   cricket::MediaSessionOptions options;
2922   options.has_audio = true;
2923   options.has_video = true;
2924   rtc::scoped_ptr<JsepSessionDescription> offer(
2925       CreateRemoteOffer(options));
2926   SetRemoteDescriptionWithoutError(offer.release());
2927
2928   mediastream_signaling_.SendAudioVideoStream1();
2929   rtc::scoped_ptr<SessionDescriptionInterface> answer(
2930       CreateAnswer(NULL));
2931   SetLocalDescriptionWithoutError(answer.release());
2932
2933   // Receive an offer without changed ufrag or password.
2934   options.transport_options.ice_restart = false;
2935   rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
2936       CreateRemoteOffer(options, session_->remote_description()));
2937   SetRemoteDescriptionWithoutError(updated_offer2.release());
2938
2939   rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
2940       CreateAnswer(NULL));
2941
2942   CompareIceUfragAndPassword(updated_answer2->description(),
2943                              session_->local_description()->description(),
2944                              true);
2945
2946   SetLocalDescriptionWithoutError(updated_answer2.release());
2947 }
2948
2949 TEST_F(WebRtcSessionTest, TestSessionContentError) {
2950   Init(NULL);
2951   mediastream_signaling_.SendAudioVideoStream1();
2952   SessionDescriptionInterface* offer = CreateOffer();
2953   const std::string session_id_orig = offer->session_id();
2954   const std::string session_version_orig = offer->session_version();
2955   SetLocalDescriptionWithoutError(offer);
2956
2957   video_channel_ = media_engine_->GetVideoChannel(0);
2958   video_channel_->set_fail_set_send_codecs(true);
2959
2960   mediastream_signaling_.SendAudioVideoStream2();
2961   SessionDescriptionInterface* answer =
2962       CreateRemoteAnswer(session_->local_description());
2963   SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
2964 }
2965
2966 // Runs the loopback call test with BUNDLE and STUN disabled.
2967 TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
2968   // Lets try with only UDP ports.
2969   allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
2970                        cricket::PORTALLOCATOR_DISABLE_TCP |
2971                        cricket::PORTALLOCATOR_DISABLE_STUN |
2972                        cricket::PORTALLOCATOR_DISABLE_RELAY);
2973   TestLoopbackCall();
2974 }
2975
2976 // Runs the loopback call test with BUNDLE and STUN enabled.
2977 TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
2978   allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
2979                        cricket::PORTALLOCATOR_ENABLE_BUNDLE |
2980                        cricket::PORTALLOCATOR_DISABLE_TCP |
2981                        cricket::PORTALLOCATOR_DISABLE_RELAY);
2982   TestLoopbackCall();
2983 }
2984
2985 TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
2986   Init(NULL);
2987   cricket::MediaSessionOptions options;
2988   options.has_audio = true;
2989   options.has_video = true;
2990
2991   cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
2992   std::string error_code_str = "ERROR_CONTENT";
2993   std::string error_desc = "Fake session error description.";
2994   session_->SetError(error_code, error_desc);
2995
2996   SessionDescriptionInterface* offer = CreateRemoteOffer(options);
2997   SessionDescriptionInterface* answer =
2998       CreateRemoteAnswer(offer, options);
2999
3000   std::string action;
3001   std::ostringstream session_error_msg;
3002   session_error_msg << kSessionError << error_code_str << ". ";
3003   session_error_msg << kSessionErrorDesc << error_desc << ".";
3004   SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
3005   SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
3006 }
3007
3008 TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
3009   constraints_.reset(new FakeConstraints());
3010   constraints_->AddOptional(
3011       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
3012   Init(NULL);
3013
3014   SetLocalDescriptionWithDataChannel();
3015   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3016 }
3017
3018 TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
3019   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3020
3021   constraints_.reset(new FakeConstraints());
3022   constraints_->AddOptional(
3023       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
3024   options_.disable_sctp_data_channels = false;
3025
3026   InitWithDtls();
3027
3028   SetLocalDescriptionWithDataChannel();
3029   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3030 }
3031
3032 TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
3033   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3034
3035   InitWithDtls();
3036
3037   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3038   EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
3039   EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3040 }
3041
3042 TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
3043   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3044   SetFactoryDtlsSrtp();
3045   InitWithDtls();
3046
3047   // Create remote offer with SCTP.
3048   cricket::MediaSessionOptions options;
3049   options.data_channel_type = cricket::DCT_SCTP;
3050   JsepSessionDescription* offer =
3051       CreateRemoteOffer(options, cricket::SEC_DISABLED);
3052   SetRemoteDescriptionWithoutError(offer);
3053
3054   // Verifies the answer contains SCTP.
3055   rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
3056   EXPECT_TRUE(answer != NULL);
3057   EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3058   EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
3059 }
3060
3061 TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
3062   constraints_.reset(new FakeConstraints());
3063   constraints_->AddOptional(
3064       webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
3065   InitWithDtls();
3066
3067   SetLocalDescriptionWithDataChannel();
3068   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3069 }
3070
3071 TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
3072   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3073
3074   InitWithDtls();
3075
3076   SetLocalDescriptionWithDataChannel();
3077   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3078 }
3079
3080 TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
3081   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3082   options_.disable_sctp_data_channels = true;
3083   InitWithDtls();
3084
3085   SetLocalDescriptionWithDataChannel();
3086   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3087 }
3088
3089 TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
3090   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3091   const int new_send_port = 9998;
3092   const int new_recv_port = 7775;
3093
3094   InitWithDtls();
3095   SetFactoryDtlsSrtp();
3096
3097   // By default, don't actually add the codecs to desc_factory_; they don't
3098   // actually get serialized for SCTP in BuildMediaDescription().  Instead,
3099   // let the session description get parsed.  That'll get the proper codecs
3100   // into the stream.
3101   cricket::MediaSessionOptions options;
3102   JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3103       "stream1", new_send_port, options);
3104
3105   // SetRemoteDescription will take the ownership of the offer.
3106   SetRemoteDescriptionWithoutError(offer);
3107
3108   SessionDescriptionInterface* answer = ChangeSDPSctpPort(
3109       new_recv_port, CreateAnswer(NULL));
3110   ASSERT_TRUE(answer != NULL);
3111
3112   // Now set the local description, which'll take ownership of the answer.
3113   SetLocalDescriptionWithoutError(answer);
3114
3115   // TEST PLAN: Set the port number to something new, set it in the SDP,
3116   // and pass it all the way down.
3117   webrtc::InternalDataChannelInit dci;
3118   dci.reliable = true;
3119   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3120   rtc::scoped_refptr<webrtc::DataChannel> dc =
3121       session_->CreateDataChannel("datachannel", &dci);
3122
3123   cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3124   int portnum = -1;
3125   ASSERT_TRUE(ch != NULL);
3126   ASSERT_EQ(1UL, ch->send_codecs().size());
3127   EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
3128   EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
3129                       ch->send_codecs()[0].name.c_str()));
3130   EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3131                                             &portnum));
3132   EXPECT_EQ(new_send_port, portnum);
3133
3134   ASSERT_EQ(1UL, ch->recv_codecs().size());
3135   EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
3136   EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
3137                       ch->recv_codecs()[0].name.c_str()));
3138   EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3139                                             &portnum));
3140   EXPECT_EQ(new_recv_port, portnum);
3141 }
3142
3143 // Verifies that CreateOffer succeeds when CreateOffer is called before async
3144 // identity generation is finished.
3145 TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
3146   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3147   InitWithDtls();
3148
3149   EXPECT_TRUE(session_->waiting_for_identity());
3150   mediastream_signaling_.SendAudioVideoStream1();
3151   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3152
3153   EXPECT_TRUE(offer != NULL);
3154   VerifyNoCryptoParams(offer->description(), true);
3155   VerifyFingerprintStatus(offer->description(), true);
3156 }
3157
3158 // Verifies that CreateAnswer succeeds when CreateOffer is called before async
3159 // identity generation is finished.
3160 TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
3161   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3162   InitWithDtls();
3163   SetFactoryDtlsSrtp();
3164
3165   cricket::MediaSessionOptions options;
3166   options.has_video = true;
3167   scoped_ptr<JsepSessionDescription> offer(
3168         CreateRemoteOffer(options, cricket::SEC_DISABLED));
3169   ASSERT_TRUE(offer.get() != NULL);
3170   SetRemoteDescriptionWithoutError(offer.release());
3171
3172   rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
3173   EXPECT_TRUE(answer != NULL);
3174   VerifyNoCryptoParams(answer->description(), true);
3175   VerifyFingerprintStatus(answer->description(), true);
3176 }
3177
3178 // Verifies that CreateOffer succeeds when CreateOffer is called after async
3179 // identity generation is finished.
3180 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
3181   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3182   InitWithDtls();
3183
3184   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
3185
3186   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3187   EXPECT_TRUE(offer != NULL);
3188 }
3189
3190 // Verifies that CreateOffer fails when CreateOffer is called after async
3191 // identity generation fails.
3192 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
3193   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3194   InitWithDtls(true);
3195
3196   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
3197
3198   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3199   EXPECT_TRUE(offer == NULL);
3200 }
3201
3202 // Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3203 // before async identity generation is finished.
3204 TEST_F(WebRtcSessionTest,
3205        TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
3206   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3207   VerifyMultipleAsyncCreateDescription(
3208       true, CreateSessionDescriptionRequest::kOffer);
3209 }
3210
3211 // Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3212 // before async identity generation fails.
3213 TEST_F(WebRtcSessionTest,
3214        TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
3215   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3216   VerifyMultipleAsyncCreateDescription(
3217       false, CreateSessionDescriptionRequest::kOffer);
3218 }
3219
3220 // Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3221 // before async identity generation is finished.
3222 TEST_F(WebRtcSessionTest,
3223        TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
3224   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3225   VerifyMultipleAsyncCreateDescription(
3226       true, CreateSessionDescriptionRequest::kAnswer);
3227 }
3228
3229 // Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3230 // before async identity generation fails.
3231 TEST_F(WebRtcSessionTest,
3232        TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
3233   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3234   VerifyMultipleAsyncCreateDescription(
3235       false, CreateSessionDescriptionRequest::kAnswer);
3236 }
3237
3238 // Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3239 // offer has no SDES crypto but only DTLS fingerprint.
3240 TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3241   // Init without DTLS.
3242   Init(NULL);
3243   // Create a remote offer with secured transport disabled.
3244   cricket::MediaSessionOptions options;
3245   JsepSessionDescription* offer(CreateRemoteOffer(
3246       options, cricket::SEC_DISABLED));
3247   // Adds a DTLS fingerprint to the remote offer.
3248   cricket::SessionDescription* sdp = offer->description();
3249   TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3250   ASSERT_TRUE(audio != NULL);
3251   ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3252   audio->description.identity_fingerprint.reset(
3253       rtc::SSLFingerprint::CreateFromRfc4572(
3254           rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
3255   SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
3256                                        offer);
3257 }
3258
3259 // This test verifies DSCP is properly applied on the media channels.
3260 TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3261   constraints_.reset(new FakeConstraints());
3262   constraints_->AddOptional(
3263       webrtc::MediaConstraintsInterface::kEnableDscp, true);
3264   Init(NULL);
3265   mediastream_signaling_.SendAudioVideoStream1();
3266   SessionDescriptionInterface* offer = CreateOffer();
3267
3268   SetLocalDescriptionWithoutError(offer);
3269
3270   video_channel_ = media_engine_->GetVideoChannel(0);
3271   voice_channel_ = media_engine_->GetVoiceChannel(0);
3272
3273   ASSERT_TRUE(video_channel_ != NULL);
3274   ASSERT_TRUE(voice_channel_ != NULL);
3275   cricket::AudioOptions audio_options;
3276   EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3277   cricket::VideoOptions video_options;
3278   EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3279   EXPECT_TRUE(audio_options.dscp.IsSet());
3280   EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3281   EXPECT_TRUE(video_options.dscp.IsSet());
3282   EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3283 }
3284
3285 TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
3286   constraints_.reset(new FakeConstraints());
3287   constraints_->AddOptional(
3288       webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3289       true);
3290   Init(NULL);
3291   mediastream_signaling_.SendAudioVideoStream1();
3292   SessionDescriptionInterface* offer = CreateOffer();
3293
3294   SetLocalDescriptionWithoutError(offer);
3295
3296   video_channel_ = media_engine_->GetVideoChannel(0);
3297
3298   ASSERT_TRUE(video_channel_ != NULL);
3299   cricket::VideoOptions video_options;
3300   EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3301   EXPECT_TRUE(
3302       video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
3303 }
3304
3305 TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
3306   // Number of unsignalled receiving streams should be between 0 and
3307   // kMaxUnsignalledRecvStreams.
3308   SetAndVerifyNumUnsignalledRecvStreams(10, 10);
3309   SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
3310                                         kMaxUnsignalledRecvStreams);
3311   SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
3312 }
3313
3314 // Tests that we can renegotiate new media content with ICE candidates in the
3315 // new remote SDP.
3316 TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
3317   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3318   InitWithDtls();
3319   SetFactoryDtlsSrtp();
3320
3321   mediastream_signaling_.UseOptionsAudioOnly();
3322   SessionDescriptionInterface* offer = CreateOffer();
3323   SetLocalDescriptionWithoutError(offer);
3324
3325   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3326   SetRemoteDescriptionWithoutError(answer);
3327
3328   cricket::MediaSessionOptions options;
3329   options.has_video = true;
3330   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3331
3332   cricket::Candidate candidate1;
3333   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
3334   candidate1.set_component(1);
3335   JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3336                                  candidate1);
3337   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3338   SetRemoteDescriptionWithoutError(offer);
3339
3340   answer = CreateAnswer(NULL);
3341   SetLocalDescriptionWithoutError(answer);
3342 }
3343
3344 // Tests that we can renegotiate new media content with ICE candidates separated
3345 // from the remote SDP.
3346 TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
3347   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3348   InitWithDtls();
3349   SetFactoryDtlsSrtp();
3350
3351   mediastream_signaling_.UseOptionsAudioOnly();
3352   SessionDescriptionInterface* offer = CreateOffer();
3353   SetLocalDescriptionWithoutError(offer);
3354
3355   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3356   SetRemoteDescriptionWithoutError(answer);
3357
3358   cricket::MediaSessionOptions options;
3359   options.has_video = true;
3360   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3361   SetRemoteDescriptionWithoutError(offer);
3362
3363   cricket::Candidate candidate1;
3364   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
3365   candidate1.set_component(1);
3366   JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3367                                  candidate1);
3368   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
3369
3370   answer = CreateAnswer(NULL);
3371   SetLocalDescriptionWithoutError(answer);
3372 }
3373
3374 // TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled.  That test
3375 // currently fails because upon disconnection and reconnection OnIceComplete is
3376 // called more than once without returning to IceGatheringGathering.