Home | History | Annotate | Download | only in webrtc
      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/videotrack.h"
     34 #include "talk/app/webrtc/test/fakeconstraints.h"
     35 #include "talk/app/webrtc/test/fakedtlsidentityservice.h"
     36 #include "talk/app/webrtc/test/fakemediastreamsignaling.h"
     37 #include "talk/app/webrtc/webrtcsession.h"
     38 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
     39 #include "talk/base/fakenetwork.h"
     40 #include "talk/base/firewallsocketserver.h"
     41 #include "talk/base/gunit.h"
     42 #include "talk/base/logging.h"
     43 #include "talk/base/network.h"
     44 #include "talk/base/physicalsocketserver.h"
     45 #include "talk/base/sslstreamadapter.h"
     46 #include "talk/base/stringutils.h"
     47 #include "talk/base/thread.h"
     48 #include "talk/base/virtualsocketserver.h"
     49 #include "talk/media/base/fakemediaengine.h"
     50 #include "talk/media/base/fakevideorenderer.h"
     51 #include "talk/media/base/mediachannel.h"
     52 #include "talk/media/devices/fakedevicemanager.h"
     53 #include "talk/p2p/base/stunserver.h"
     54 #include "talk/p2p/base/teststunserver.h"
     55 #include "talk/p2p/client/basicportallocator.h"
     56 #include "talk/session/media/channelmanager.h"
     57 #include "talk/session/media/mediasession.h"
     58 
     59 #define MAYBE_SKIP_TEST(feature)                    \
     60   if (!(feature())) {                               \
     61     LOG(LS_INFO) << "Feature disabled... skipping"; \
     62     return;                                         \
     63   }
     64 
     65 using cricket::BaseSession;
     66 using cricket::DF_PLAY;
     67 using cricket::DF_SEND;
     68 using cricket::FakeVoiceMediaChannel;
     69 using cricket::NS_GINGLE_P2P;
     70 using cricket::NS_JINGLE_ICE_UDP;
     71 using cricket::TransportInfo;
     72 using talk_base::SocketAddress;
     73 using talk_base::scoped_ptr;
     74 using webrtc::CreateSessionDescription;
     75 using webrtc::CreateSessionDescriptionObserver;
     76 using webrtc::CreateSessionDescriptionRequest;
     77 using webrtc::DTLSIdentityRequestObserver;
     78 using webrtc::DTLSIdentityServiceInterface;
     79 using webrtc::FakeConstraints;
     80 using webrtc::IceCandidateCollection;
     81 using webrtc::JsepIceCandidate;
     82 using webrtc::JsepSessionDescription;
     83 using webrtc::PeerConnectionInterface;
     84 using webrtc::SessionDescriptionInterface;
     85 using webrtc::StreamCollection;
     86 using webrtc::WebRtcSession;
     87 using webrtc::kMlineMismatch;
     88 using webrtc::kSdpWithoutCrypto;
     89 using webrtc::kSessionError;
     90 using webrtc::kSetLocalSdpFailed;
     91 using webrtc::kSetRemoteSdpFailed;
     92 using webrtc::kPushDownAnswerTDFailed;
     93 using webrtc::kPushDownPranswerTDFailed;
     94 using webrtc::kBundleWithoutRtcpMux;
     95 
     96 static const SocketAddress kClientAddr1("11.11.11.11", 0);
     97 static const SocketAddress kClientAddr2("22.22.22.22", 0);
     98 static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
     99 
    100 static const char kSessionVersion[] = "1";
    101 
    102 // Media index of candidates belonging to the first media content.
    103 static const int kMediaContentIndex0 = 0;
    104 static const char kMediaContentName0[] = "audio";
    105 
    106 // Media index of candidates belonging to the second media content.
    107 static const int kMediaContentIndex1 = 1;
    108 static const char kMediaContentName1[] = "video";
    109 
    110 static const int kIceCandidatesTimeout = 10000;
    111 
    112 static const cricket::AudioCodec
    113     kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
    114 static const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
    115 static const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
    116 
    117 // Add some extra |newlines| to the |message| after |line|.
    118 static void InjectAfter(const std::string& line,
    119                         const std::string& newlines,
    120                         std::string* message) {
    121   const std::string tmp = line + newlines;
    122   talk_base::replace_substrs(line.c_str(), line.length(),
    123                              tmp.c_str(), tmp.length(), message);
    124 }
    125 
    126 class MockIceObserver : public webrtc::IceObserver {
    127  public:
    128   MockIceObserver()
    129       : oncandidatesready_(false),
    130         ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
    131         ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
    132   }
    133 
    134   virtual void OnIceConnectionChange(
    135       PeerConnectionInterface::IceConnectionState new_state) {
    136     ice_connection_state_ = new_state;
    137   }
    138   virtual void OnIceGatheringChange(
    139       PeerConnectionInterface::IceGatheringState new_state) {
    140     // We can never transition back to "new".
    141     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
    142     ice_gathering_state_ = new_state;
    143 
    144     // oncandidatesready_ really means "ICE gathering is complete".
    145     // This if statement ensures that this value remains correct when we
    146     // transition from kIceGatheringComplete to kIceGatheringGathering.
    147     if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
    148       oncandidatesready_ = false;
    149     }
    150   }
    151 
    152   // Found a new candidate.
    153   virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
    154     if (candidate->sdp_mline_index() == kMediaContentIndex0) {
    155       mline_0_candidates_.push_back(candidate->candidate());
    156     } else if (candidate->sdp_mline_index() == kMediaContentIndex1) {
    157       mline_1_candidates_.push_back(candidate->candidate());
    158     }
    159     // The ICE gathering state should always be Gathering when a candidate is
    160     // received (or possibly Completed in the case of the final candidate).
    161     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
    162   }
    163 
    164   // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
    165   virtual void OnIceComplete() {
    166     EXPECT_FALSE(oncandidatesready_);
    167     oncandidatesready_ = true;
    168 
    169     // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
    170     // be called approximately simultaneously.  For ease of testing, this
    171     // check additionally requires that they be called in the above order.
    172     EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
    173               ice_gathering_state_);
    174   }
    175 
    176   bool oncandidatesready_;
    177   std::vector<cricket::Candidate> mline_0_candidates_;
    178   std::vector<cricket::Candidate> mline_1_candidates_;
    179   PeerConnectionInterface::IceConnectionState ice_connection_state_;
    180   PeerConnectionInterface::IceGatheringState ice_gathering_state_;
    181 };
    182 
    183 class WebRtcSessionForTest : public webrtc::WebRtcSession {
    184  public:
    185   WebRtcSessionForTest(cricket::ChannelManager* cmgr,
    186                        talk_base::Thread* signaling_thread,
    187                        talk_base::Thread* worker_thread,
    188                        cricket::PortAllocator* port_allocator,
    189                        webrtc::IceObserver* ice_observer,
    190                        webrtc::MediaStreamSignaling* mediastream_signaling)
    191     : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
    192                     mediastream_signaling) {
    193     RegisterIceObserver(ice_observer);
    194   }
    195   virtual ~WebRtcSessionForTest() {}
    196 
    197   using cricket::BaseSession::GetTransportProxy;
    198   using webrtc::WebRtcSession::SetAudioPlayout;
    199   using webrtc::WebRtcSession::SetAudioSend;
    200   using webrtc::WebRtcSession::SetCaptureDevice;
    201   using webrtc::WebRtcSession::SetVideoPlayout;
    202   using webrtc::WebRtcSession::SetVideoSend;
    203 };
    204 
    205 class WebRtcSessionCreateSDPObserverForTest
    206     : public talk_base::RefCountedObject<CreateSessionDescriptionObserver> {
    207  public:
    208   enum State {
    209     kInit,
    210     kFailed,
    211     kSucceeded,
    212   };
    213   WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
    214 
    215   // CreateSessionDescriptionObserver implementation.
    216   virtual void OnSuccess(SessionDescriptionInterface* desc) {
    217     description_.reset(desc);
    218     state_ = kSucceeded;
    219   }
    220   virtual void OnFailure(const std::string& error) {
    221     state_ = kFailed;
    222   }
    223 
    224   SessionDescriptionInterface* description() { return description_.get(); }
    225 
    226   SessionDescriptionInterface* ReleaseDescription() {
    227     return description_.release();
    228   }
    229 
    230   State state() const { return state_; }
    231 
    232  protected:
    233   ~WebRtcSessionCreateSDPObserverForTest() {}
    234 
    235  private:
    236   talk_base::scoped_ptr<SessionDescriptionInterface> description_;
    237   State state_;
    238 };
    239 
    240 class FakeAudioRenderer : public cricket::AudioRenderer {
    241  public:
    242   FakeAudioRenderer() : channel_id_(-1) {}
    243 
    244   virtual void AddChannel(int channel_id) OVERRIDE {
    245     ASSERT(channel_id_ == -1);
    246     channel_id_ = channel_id;
    247   }
    248   virtual void RemoveChannel(int channel_id) OVERRIDE {
    249     ASSERT(channel_id == channel_id_);
    250     channel_id_ = -1;
    251   }
    252 
    253   int channel_id() const { return channel_id_; }
    254  private:
    255   int channel_id_;
    256 };
    257 
    258 class WebRtcSessionTest : public testing::Test {
    259  protected:
    260   // TODO Investigate why ChannelManager crashes, if it's created
    261   // after stun_server.
    262   WebRtcSessionTest()
    263     : media_engine_(new cricket::FakeMediaEngine()),
    264       data_engine_(new cricket::FakeDataEngine()),
    265       device_manager_(new cricket::FakeDeviceManager()),
    266       channel_manager_(new cricket::ChannelManager(
    267          media_engine_, data_engine_, device_manager_,
    268          new cricket::CaptureManager(), talk_base::Thread::Current())),
    269       tdesc_factory_(new cricket::TransportDescriptionFactory()),
    270       desc_factory_(new cricket::MediaSessionDescriptionFactory(
    271           channel_manager_.get(), tdesc_factory_.get())),
    272       pss_(new talk_base::PhysicalSocketServer),
    273       vss_(new talk_base::VirtualSocketServer(pss_.get())),
    274       fss_(new talk_base::FirewallSocketServer(vss_.get())),
    275       ss_scope_(fss_.get()),
    276       stun_server_(talk_base::Thread::Current(), kStunAddr),
    277       allocator_(&network_manager_, kStunAddr,
    278                  SocketAddress(), SocketAddress(), SocketAddress()) {
    279     tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
    280     allocator_.set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
    281                          cricket::PORTALLOCATOR_DISABLE_RELAY |
    282                          cricket::PORTALLOCATOR_ENABLE_BUNDLE);
    283     EXPECT_TRUE(channel_manager_->Init());
    284     desc_factory_->set_add_legacy_streams(false);
    285   }
    286 
    287   void AddInterface(const SocketAddress& addr) {
    288     network_manager_.AddInterface(addr);
    289   }
    290 
    291   void Init(DTLSIdentityServiceInterface* identity_service) {
    292     ASSERT_TRUE(session_.get() == NULL);
    293     session_.reset(new WebRtcSessionForTest(
    294         channel_manager_.get(), talk_base::Thread::Current(),
    295         talk_base::Thread::Current(), &allocator_,
    296         &observer_,
    297         &mediastream_signaling_));
    298 
    299     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
    300         observer_.ice_connection_state_);
    301     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
    302         observer_.ice_gathering_state_);
    303 
    304     EXPECT_TRUE(session_->Initialize(constraints_.get(), identity_service));
    305   }
    306 
    307   void InitWithDtmfCodec() {
    308     // Add kTelephoneEventCodec for dtmf test.
    309     std::vector<cricket::AudioCodec> codecs;
    310     codecs.push_back(kTelephoneEventCodec);
    311     media_engine_->SetAudioCodecs(codecs);
    312     desc_factory_->set_audio_codecs(codecs);
    313     Init(NULL);
    314   }
    315 
    316   void InitWithDtls() {
    317     constraints_.reset(new FakeConstraints());
    318     constraints_->AddOptional(
    319         webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, true);
    320 
    321     Init(NULL);
    322   }
    323 
    324   void InitWithAsyncDtls(bool identity_request_should_fail) {
    325     constraints_.reset(new FakeConstraints());
    326     constraints_->AddOptional(
    327         webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, true);
    328     FakeIdentityService* identity_service = new FakeIdentityService();
    329     identity_service->set_should_fail(identity_request_should_fail);
    330     Init(identity_service);
    331   }
    332 
    333   // Creates a local offer and applies it. Starts ice.
    334   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
    335   // to decide which streams to create.
    336   void InitiateCall() {
    337     SessionDescriptionInterface* offer = CreateOffer(NULL);
    338     SetLocalDescriptionWithoutError(offer);
    339     EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
    340         observer_.ice_gathering_state_,
    341         kIceCandidatesTimeout);
    342   }
    343 
    344   SessionDescriptionInterface* CreateOffer(
    345       const webrtc::MediaConstraintsInterface* constraints) {
    346     talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
    347         observer = new WebRtcSessionCreateSDPObserverForTest();
    348     session_->CreateOffer(observer, constraints);
    349     EXPECT_TRUE_WAIT(
    350         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
    351         1000);
    352     return observer->ReleaseDescription();
    353   }
    354 
    355   SessionDescriptionInterface* CreateAnswer(
    356       const webrtc::MediaConstraintsInterface* constraints) {
    357     talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
    358         = new WebRtcSessionCreateSDPObserverForTest();
    359     session_->CreateAnswer(observer, constraints);
    360     EXPECT_TRUE_WAIT(
    361         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
    362         1000);
    363     return observer->ReleaseDescription();
    364   }
    365 
    366   bool ChannelsExist() {
    367     return (session_->voice_channel() != NULL &&
    368             session_->video_channel() != NULL);
    369   }
    370 
    371   void CheckTransportChannels() {
    372     EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
    373     EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
    374     EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
    375     EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
    376   }
    377 
    378   void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
    379     ASSERT_TRUE(session_.get() != NULL);
    380     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
    381     ASSERT_TRUE(content != NULL);
    382     const cricket::AudioContentDescription* audio_content =
    383         static_cast<const cricket::AudioContentDescription*>(
    384             content->description);
    385     ASSERT_TRUE(audio_content != NULL);
    386     ASSERT_EQ(1U, audio_content->cryptos().size());
    387     ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
    388     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
    389               audio_content->cryptos()[0].cipher_suite);
    390     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    391               audio_content->protocol());
    392 
    393     content = cricket::GetFirstVideoContent(sdp);
    394     ASSERT_TRUE(content != NULL);
    395     const cricket::VideoContentDescription* video_content =
    396         static_cast<const cricket::VideoContentDescription*>(
    397             content->description);
    398     ASSERT_TRUE(video_content != NULL);
    399     ASSERT_EQ(1U, video_content->cryptos().size());
    400     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
    401               video_content->cryptos()[0].cipher_suite);
    402     ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
    403     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    404               video_content->protocol());
    405   }
    406 
    407   void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
    408     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
    409     ASSERT_TRUE(content != NULL);
    410     const cricket::AudioContentDescription* audio_content =
    411         static_cast<const cricket::AudioContentDescription*>(
    412             content->description);
    413     ASSERT_TRUE(audio_content != NULL);
    414     ASSERT_EQ(0U, audio_content->cryptos().size());
    415 
    416     content = cricket::GetFirstVideoContent(sdp);
    417     ASSERT_TRUE(content != NULL);
    418     const cricket::VideoContentDescription* video_content =
    419         static_cast<const cricket::VideoContentDescription*>(
    420             content->description);
    421     ASSERT_TRUE(video_content != NULL);
    422     ASSERT_EQ(0U, video_content->cryptos().size());
    423 
    424     if (dtls) {
    425       EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    426                 audio_content->protocol());
    427       EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    428                 video_content->protocol());
    429     } else {
    430       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
    431                 audio_content->protocol());
    432       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
    433                 video_content->protocol());
    434     }
    435   }
    436 
    437   // Set the internal fake description factories to do DTLS-SRTP.
    438   void SetFactoryDtlsSrtp() {
    439     desc_factory_->set_secure(cricket::SEC_ENABLED);
    440     std::string identity_name = "WebRTC" +
    441         talk_base::ToString(talk_base::CreateRandomId());
    442     identity_.reset(talk_base::SSLIdentity::Generate(identity_name));
    443     tdesc_factory_->set_identity(identity_.get());
    444     tdesc_factory_->set_digest_algorithm(talk_base::DIGEST_SHA_256);
    445     tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
    446   }
    447 
    448   void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
    449                                bool expected) {
    450     const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
    451     ASSERT_TRUE(audio != NULL);
    452     ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
    453     if (expected) {
    454       ASSERT_EQ(std::string(talk_base::DIGEST_SHA_256), audio->description.
    455                 identity_fingerprint->algorithm);
    456     }
    457     const TransportInfo* video = sdp->GetTransportInfoByName("video");
    458     ASSERT_TRUE(video != NULL);
    459     ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
    460     if (expected) {
    461       ASSERT_EQ(std::string(talk_base::DIGEST_SHA_256), video->description.
    462                 identity_fingerprint->algorithm);
    463     }
    464   }
    465 
    466   void VerifyAnswerFromNonCryptoOffer() {
    467     // Create a SDP without Crypto.
    468     cricket::MediaSessionOptions options;
    469     options.has_video = true;
    470     JsepSessionDescription* offer(
    471         CreateRemoteOffer(options, cricket::SEC_DISABLED));
    472     ASSERT_TRUE(offer != NULL);
    473     VerifyNoCryptoParams(offer->description(), false);
    474     SetRemoteDescriptionExpectError("Called with a SDP without crypto enabled",
    475                                      offer);
    476     const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
    477     // Answer should be NULL as no crypto params in offer.
    478     ASSERT_TRUE(answer == NULL);
    479   }
    480 
    481   void VerifyAnswerFromCryptoOffer() {
    482     cricket::MediaSessionOptions options;
    483     options.has_video = true;
    484     options.bundle_enabled = true;
    485     scoped_ptr<JsepSessionDescription> offer(
    486         CreateRemoteOffer(options, cricket::SEC_REQUIRED));
    487     ASSERT_TRUE(offer.get() != NULL);
    488     VerifyCryptoParams(offer->description());
    489     SetRemoteDescriptionWithoutError(offer.release());
    490     scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
    491     ASSERT_TRUE(answer.get() != NULL);
    492     VerifyCryptoParams(answer->description());
    493   }
    494 
    495   void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
    496                                   const cricket::SessionDescription* desc2,
    497                                   bool expect_equal) {
    498     if (desc1->contents().size() != desc2->contents().size()) {
    499       EXPECT_FALSE(expect_equal);
    500       return;
    501     }
    502 
    503     const cricket::ContentInfos& contents = desc1->contents();
    504     cricket::ContentInfos::const_iterator it = contents.begin();
    505 
    506     for (; it != contents.end(); ++it) {
    507       const cricket::TransportDescription* transport_desc1 =
    508           desc1->GetTransportDescriptionByName(it->name);
    509       const cricket::TransportDescription* transport_desc2 =
    510           desc2->GetTransportDescriptionByName(it->name);
    511       if (!transport_desc1 || !transport_desc2) {
    512         EXPECT_FALSE(expect_equal);
    513         return;
    514       }
    515       if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
    516           transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
    517         EXPECT_FALSE(expect_equal);
    518         return;
    519       }
    520     }
    521     EXPECT_TRUE(expect_equal);
    522   }
    523   // Creates a remote offer and and applies it as a remote description,
    524   // creates a local answer and applies is as a local description.
    525   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
    526   // to decide which local and remote streams to create.
    527   void CreateAndSetRemoteOfferAndLocalAnswer() {
    528     SessionDescriptionInterface* offer = CreateRemoteOffer();
    529     SetRemoteDescriptionWithoutError(offer);
    530     SessionDescriptionInterface* answer = CreateAnswer(NULL);
    531     SetLocalDescriptionWithoutError(answer);
    532   }
    533   void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
    534     EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
    535   }
    536   void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
    537                                       BaseSession::State expected_state) {
    538     SetLocalDescriptionWithoutError(desc);
    539     EXPECT_EQ(expected_state, session_->state());
    540   }
    541   void SetLocalDescriptionExpectError(const std::string& expected_error,
    542                                       SessionDescriptionInterface* desc) {
    543     std::string error;
    544     EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
    545     EXPECT_NE(std::string::npos, error.find(kSetLocalSdpFailed));
    546     EXPECT_NE(std::string::npos, error.find(expected_error));
    547   }
    548   void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
    549     EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
    550   }
    551   void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
    552                                        BaseSession::State expected_state) {
    553     SetRemoteDescriptionWithoutError(desc);
    554     EXPECT_EQ(expected_state, session_->state());
    555   }
    556   void SetRemoteDescriptionExpectError(const std::string& expected_error,
    557                                        SessionDescriptionInterface* desc) {
    558     std::string error;
    559     EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
    560     EXPECT_NE(std::string::npos, error.find(kSetRemoteSdpFailed));
    561     EXPECT_NE(std::string::npos, error.find(expected_error));
    562   }
    563 
    564   void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
    565       SessionDescriptionInterface** nocrypto_answer) {
    566     // Create a SDP without Crypto.
    567     cricket::MediaSessionOptions options;
    568     options.has_video = true;
    569     options.bundle_enabled = true;
    570     *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
    571     ASSERT_TRUE(*offer != NULL);
    572     VerifyCryptoParams((*offer)->description());
    573 
    574     *nocrypto_answer = CreateRemoteAnswer(*offer, options,
    575                                           cricket::SEC_DISABLED);
    576     EXPECT_TRUE(*nocrypto_answer != NULL);
    577   }
    578 
    579   JsepSessionDescription* CreateRemoteOfferWithVersion(
    580         cricket::MediaSessionOptions options,
    581         cricket::SecurePolicy secure_policy,
    582         const std::string& session_version,
    583         const SessionDescriptionInterface* current_desc) {
    584     std::string session_id = talk_base::ToString(talk_base::CreateRandomId64());
    585     const cricket::SessionDescription* cricket_desc = NULL;
    586     if (current_desc) {
    587       cricket_desc = current_desc->description();
    588       session_id = current_desc->session_id();
    589     }
    590 
    591     desc_factory_->set_secure(secure_policy);
    592     JsepSessionDescription* offer(
    593         new JsepSessionDescription(JsepSessionDescription::kOffer));
    594     if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
    595                            session_id, session_version)) {
    596       delete offer;
    597       offer = NULL;
    598     }
    599     return offer;
    600   }
    601   JsepSessionDescription* CreateRemoteOffer(
    602       cricket::MediaSessionOptions options) {
    603     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
    604                                         kSessionVersion, NULL);
    605   }
    606   JsepSessionDescription* CreateRemoteOffer(
    607       cricket::MediaSessionOptions options, cricket::SecurePolicy policy) {
    608     return CreateRemoteOfferWithVersion(options, policy, kSessionVersion, NULL);
    609   }
    610   JsepSessionDescription* CreateRemoteOffer(
    611       cricket::MediaSessionOptions options,
    612       const SessionDescriptionInterface* current_desc) {
    613     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
    614                                         kSessionVersion, current_desc);
    615   }
    616 
    617   // Create a remote offer. Call mediastream_signaling_.UseOptionsWithStreamX()
    618   // before this function to decide which streams to create.
    619   JsepSessionDescription* CreateRemoteOffer() {
    620     cricket::MediaSessionOptions options;
    621     mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
    622     return CreateRemoteOffer(options, session_->remote_description());
    623   }
    624 
    625   JsepSessionDescription* CreateRemoteAnswer(
    626       const SessionDescriptionInterface* offer,
    627       cricket::MediaSessionOptions options,
    628       cricket::SecurePolicy policy) {
    629     desc_factory_->set_secure(policy);
    630     const std::string session_id =
    631         talk_base::ToString(talk_base::CreateRandomId64());
    632     JsepSessionDescription* answer(
    633         new JsepSessionDescription(JsepSessionDescription::kAnswer));
    634     if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
    635                                                         options, NULL),
    636                             session_id, kSessionVersion)) {
    637       delete answer;
    638       answer = NULL;
    639     }
    640     return answer;
    641   }
    642 
    643   JsepSessionDescription* CreateRemoteAnswer(
    644       const SessionDescriptionInterface* offer,
    645       cricket::MediaSessionOptions options) {
    646       return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
    647   }
    648 
    649   // Creates an answer session description with streams based on
    650   // |mediastream_signaling_|. Call
    651   // mediastream_signaling_.UseOptionsWithStreamX() before this function
    652   // to decide which streams to create.
    653   JsepSessionDescription* CreateRemoteAnswer(
    654       const SessionDescriptionInterface* offer) {
    655     cricket::MediaSessionOptions options;
    656     mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
    657     return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
    658   }
    659 
    660   void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
    661     AddInterface(kClientAddr1);
    662     Init(NULL);
    663     mediastream_signaling_.SendAudioVideoStream1();
    664     FakeConstraints constraints;
    665     constraints.SetMandatoryUseRtpMux(bundle);
    666     SessionDescriptionInterface* offer = CreateOffer(&constraints);
    667     // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
    668     // and answer.
    669     SetLocalDescriptionWithoutError(offer);
    670 
    671     talk_base::scoped_ptr<SessionDescriptionInterface> answer(
    672         CreateRemoteAnswer(session_->local_description()));
    673     std::string sdp;
    674     EXPECT_TRUE(answer->ToString(&sdp));
    675 
    676     size_t expected_candidate_num = 2;
    677     if (!rtcp_mux) {
    678       // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
    679       // for rtp and rtcp.
    680       expected_candidate_num = 4;
    681       // Disable rtcp-mux from the answer
    682       const std::string kRtcpMux = "a=rtcp-mux";
    683       const std::string kXRtcpMux = "a=xrtcp-mux";
    684       talk_base::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
    685                                  kXRtcpMux.c_str(), kXRtcpMux.length(),
    686                                  &sdp);
    687     }
    688 
    689     SessionDescriptionInterface* new_answer = CreateSessionDescription(
    690         JsepSessionDescription::kAnswer, sdp, NULL);
    691 
    692     // SetRemoteDescription to enable rtcp mux.
    693     SetRemoteDescriptionWithoutError(new_answer);
    694     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
    695     EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
    696     EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
    697     for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
    698       cricket::Candidate c0 = observer_.mline_0_candidates_[i];
    699       cricket::Candidate c1 = observer_.mline_1_candidates_[i];
    700       if (bundle) {
    701         EXPECT_TRUE(c0.IsEquivalent(c1));
    702       } else {
    703         EXPECT_FALSE(c0.IsEquivalent(c1));
    704       }
    705     }
    706   }
    707   // Tests that we can only send DTMF when the dtmf codec is supported.
    708   void TestCanInsertDtmf(bool can) {
    709     if (can) {
    710       InitWithDtmfCodec();
    711     } else {
    712       Init(NULL);
    713     }
    714     mediastream_signaling_.SendAudioVideoStream1();
    715     CreateAndSetRemoteOfferAndLocalAnswer();
    716     EXPECT_FALSE(session_->CanInsertDtmf(""));
    717     EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
    718   }
    719 
    720   // The method sets up a call from the session to itself, in a loopback
    721   // arrangement.  It also uses a firewall rule to create a temporary
    722   // disconnection.  This code is placed as a method so that it can be invoked
    723   // by multiple tests with different allocators (e.g. with and without BUNDLE).
    724   // While running the call, this method also checks if the session goes through
    725   // the correct sequence of ICE states when a connection is established,
    726   // broken, and re-established.
    727   // The Connection state should go:
    728   // New -> Checking -> Connected -> Disconnected -> Connected.
    729   // The Gathering state should go: New -> Gathering -> Completed.
    730   void TestLoopbackCall() {
    731     AddInterface(kClientAddr1);
    732     Init(NULL);
    733     mediastream_signaling_.SendAudioVideoStream1();
    734     SessionDescriptionInterface* offer = CreateOffer(NULL);
    735 
    736     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
    737               observer_.ice_gathering_state_);
    738     SetLocalDescriptionWithoutError(offer);
    739     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
    740               observer_.ice_connection_state_);
    741     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
    742                    observer_.ice_gathering_state_,
    743                    kIceCandidatesTimeout);
    744     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
    745     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
    746                    observer_.ice_gathering_state_,
    747                    kIceCandidatesTimeout);
    748 
    749     std::string sdp;
    750     offer->ToString(&sdp);
    751     SessionDescriptionInterface* desc =
    752         webrtc::CreateSessionDescription(JsepSessionDescription::kAnswer, sdp);
    753     ASSERT_TRUE(desc != NULL);
    754     SetRemoteDescriptionWithoutError(desc);
    755 
    756     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
    757                    observer_.ice_connection_state_,
    758                    kIceCandidatesTimeout);
    759     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionConnected,
    760                    observer_.ice_connection_state_,
    761                    kIceCandidatesTimeout);
    762     // TODO(bemasc): EXPECT(Completed) once the details are standardized.
    763 
    764     // Adding firewall rule to block ping requests, which should cause
    765     // transport channel failure.
    766     fss_->AddRule(false, talk_base::FP_ANY, talk_base::FD_ANY, kClientAddr1);
    767     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
    768                    observer_.ice_connection_state_,
    769                    kIceCandidatesTimeout);
    770 
    771     // Clearing the rules, session should move back to completed state.
    772     fss_->ClearRules();
    773     // Session is automatically calling OnSignalingReady after creation of
    774     // new portallocator session which will allocate new set of candidates.
    775 
    776     // TODO(bemasc): Change this to Completed once the details are standardized.
    777     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionConnected,
    778                    observer_.ice_connection_state_,
    779                    kIceCandidatesTimeout);
    780   }
    781 
    782   void VerifyTransportType(const std::string& content_name,
    783                            cricket::TransportProtocol protocol) {
    784     const cricket::Transport* transport = session_->GetTransport(content_name);
    785     ASSERT_TRUE(transport != NULL);
    786     EXPECT_EQ(protocol, transport->protocol());
    787   }
    788 
    789   // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
    790   void AddCNCodecs() {
    791     // Add kTelephoneEventCodec for dtmf test.
    792     std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
    793     codecs.push_back(kCNCodec1);
    794     codecs.push_back(kCNCodec2);
    795     media_engine_->SetAudioCodecs(codecs);
    796     desc_factory_->set_audio_codecs(codecs);
    797   }
    798 
    799   bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
    800     const cricket::ContentDescription* description = content->description;
    801     ASSERT(description != NULL);
    802     const cricket::AudioContentDescription* audio_content_desc =
    803         static_cast<const cricket::AudioContentDescription*>(description);
    804     ASSERT(audio_content_desc != NULL);
    805     for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
    806       if (audio_content_desc->codecs()[i].name == "CN")
    807         return false;
    808     }
    809     return true;
    810   }
    811 
    812   void SetLocalDescriptionWithDataChannel() {
    813     webrtc::DataChannelInit dci;
    814     dci.reliable = false;
    815     session_->CreateDataChannel("datachannel", &dci);
    816     SessionDescriptionInterface* offer = CreateOffer(NULL);
    817     SetLocalDescriptionWithoutError(offer);
    818   }
    819 
    820   void VerifyMultipleAsyncCreateDescription(
    821       bool success, CreateSessionDescriptionRequest::Type type) {
    822     InitWithAsyncDtls(!success);
    823 
    824     if (type == CreateSessionDescriptionRequest::kAnswer) {
    825       cricket::MediaSessionOptions options;
    826       scoped_ptr<JsepSessionDescription> offer(
    827             CreateRemoteOffer(options, cricket::SEC_REQUIRED));
    828       ASSERT_TRUE(offer.get() != NULL);
    829       SetRemoteDescriptionWithoutError(offer.release());
    830     }
    831 
    832     const int kNumber = 3;
    833     talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
    834         observers[kNumber];
    835     for (int i = 0; i < kNumber; ++i) {
    836       observers[i] = new WebRtcSessionCreateSDPObserverForTest();
    837       if (type == CreateSessionDescriptionRequest::kOffer) {
    838         session_->CreateOffer(observers[i], NULL);
    839       } else {
    840         session_->CreateAnswer(observers[i], NULL);
    841       }
    842     }
    843 
    844     WebRtcSessionCreateSDPObserverForTest::State expected_state =
    845         success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
    846                   WebRtcSessionCreateSDPObserverForTest::kFailed;
    847 
    848     for (int i = 0; i < kNumber; ++i) {
    849       EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
    850       if (success) {
    851         EXPECT_TRUE(observers[i]->description() != NULL);
    852       } else {
    853         EXPECT_TRUE(observers[i]->description() == NULL);
    854       }
    855     }
    856   }
    857 
    858   cricket::FakeMediaEngine* media_engine_;
    859   cricket::FakeDataEngine* data_engine_;
    860   cricket::FakeDeviceManager* device_manager_;
    861   talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
    862   talk_base::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
    863   talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
    864   talk_base::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
    865   talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
    866   talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
    867   talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
    868   talk_base::SocketServerScope ss_scope_;
    869   cricket::TestStunServer stun_server_;
    870   talk_base::FakeNetworkManager network_manager_;
    871   cricket::BasicPortAllocator allocator_;
    872   talk_base::scoped_ptr<FakeConstraints> constraints_;
    873   FakeMediaStreamSignaling mediastream_signaling_;
    874   talk_base::scoped_ptr<WebRtcSessionForTest> session_;
    875   MockIceObserver observer_;
    876   cricket::FakeVideoMediaChannel* video_channel_;
    877   cricket::FakeVoiceMediaChannel* voice_channel_;
    878 };
    879 
    880 TEST_F(WebRtcSessionTest, TestInitialize) {
    881   Init(NULL);
    882 }
    883 
    884 TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
    885   InitWithDtls();
    886 }
    887 
    888 // Verifies that WebRtcSession uses SEC_REQUIRED by default.
    889 TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
    890   Init(NULL);
    891   EXPECT_EQ(cricket::SEC_REQUIRED, session_->secure_policy());
    892 }
    893 
    894 TEST_F(WebRtcSessionTest, TestSessionCandidates) {
    895   TestSessionCandidatesWithBundleRtcpMux(false, false);
    896 }
    897 
    898 // Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
    899 // with rtcp-mux and/or bundle.
    900 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
    901   TestSessionCandidatesWithBundleRtcpMux(false, true);
    902 }
    903 
    904 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
    905   TestSessionCandidatesWithBundleRtcpMux(true, true);
    906 }
    907 
    908 TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
    909   AddInterface(kClientAddr1);
    910   AddInterface(kClientAddr2);
    911   Init(NULL);
    912   mediastream_signaling_.SendAudioVideoStream1();
    913   InitiateCall();
    914   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
    915   EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
    916   EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
    917 }
    918 
    919 TEST_F(WebRtcSessionTest, TestStunError) {
    920   AddInterface(kClientAddr1);
    921   AddInterface(kClientAddr2);
    922   fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr1);
    923   Init(NULL);
    924   mediastream_signaling_.SendAudioVideoStream1();
    925   InitiateCall();
    926   // Since kClientAddr1 is blocked, not expecting stun candidates for it.
    927   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
    928   EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
    929   EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
    930 }
    931 
    932 // Test creating offers and receive answers and make sure the
    933 // media engine creates the expected send and receive streams.
    934 TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
    935   Init(NULL);
    936   mediastream_signaling_.SendAudioVideoStream1();
    937   SessionDescriptionInterface* offer = CreateOffer(NULL);
    938   const std::string session_id_orig = offer->session_id();
    939   const std::string session_version_orig = offer->session_version();
    940   SetLocalDescriptionWithoutError(offer);
    941 
    942   mediastream_signaling_.SendAudioVideoStream2();
    943   SessionDescriptionInterface* answer =
    944       CreateRemoteAnswer(session_->local_description());
    945   SetRemoteDescriptionWithoutError(answer);
    946 
    947   video_channel_ = media_engine_->GetVideoChannel(0);
    948   voice_channel_ = media_engine_->GetVoiceChannel(0);
    949 
    950   ASSERT_EQ(1u, video_channel_->recv_streams().size());
    951   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
    952 
    953   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
    954   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
    955 
    956   ASSERT_EQ(1u, video_channel_->send_streams().size());
    957   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
    958   ASSERT_EQ(1u, voice_channel_->send_streams().size());
    959   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
    960 
    961   // Create new offer without send streams.
    962   mediastream_signaling_.SendNothing();
    963   offer = CreateOffer(NULL);
    964 
    965   // Verify the session id is the same and the session version is
    966   // increased.
    967   EXPECT_EQ(session_id_orig, offer->session_id());
    968   EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
    969             talk_base::FromString<uint64>(offer->session_version()));
    970 
    971   SetLocalDescriptionWithoutError(offer);
    972 
    973   mediastream_signaling_.SendAudioVideoStream2();
    974   answer = CreateRemoteAnswer(session_->local_description());
    975   SetRemoteDescriptionWithoutError(answer);
    976 
    977   EXPECT_EQ(0u, video_channel_->send_streams().size());
    978   EXPECT_EQ(0u, voice_channel_->send_streams().size());
    979 
    980   // Make sure the receive streams have not changed.
    981   ASSERT_EQ(1u, video_channel_->recv_streams().size());
    982   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
    983   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
    984   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
    985 }
    986 
    987 // Test receiving offers and creating answers and make sure the
    988 // media engine creates the expected send and receive streams.
    989 TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
    990   Init(NULL);
    991   mediastream_signaling_.SendAudioVideoStream2();
    992   SessionDescriptionInterface* offer = CreateOffer(NULL);
    993   SetRemoteDescriptionWithoutError(offer);
    994 
    995   mediastream_signaling_.SendAudioVideoStream1();
    996   SessionDescriptionInterface* answer = CreateAnswer(NULL);
    997   SetLocalDescriptionWithoutError(answer);
    998 
    999   const std::string session_id_orig = answer->session_id();
   1000   const std::string session_version_orig = answer->session_version();
   1001 
   1002   video_channel_ = media_engine_->GetVideoChannel(0);
   1003   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1004 
   1005   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1006   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
   1007 
   1008   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1009   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
   1010 
   1011   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1012   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
   1013   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1014   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
   1015 
   1016   mediastream_signaling_.SendAudioVideoStream1And2();
   1017   offer = CreateOffer(NULL);
   1018   SetRemoteDescriptionWithoutError(offer);
   1019 
   1020   // Answer by turning off all send streams.
   1021   mediastream_signaling_.SendNothing();
   1022   answer = CreateAnswer(NULL);
   1023 
   1024   // Verify the session id is the same and the session version is
   1025   // increased.
   1026   EXPECT_EQ(session_id_orig, answer->session_id());
   1027   EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
   1028             talk_base::FromString<uint64>(answer->session_version()));
   1029   SetLocalDescriptionWithoutError(answer);
   1030 
   1031   ASSERT_EQ(2u, video_channel_->recv_streams().size());
   1032   EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
   1033   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
   1034   ASSERT_EQ(2u, voice_channel_->recv_streams().size());
   1035   EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
   1036   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
   1037 
   1038   // Make sure we have no send streams.
   1039   EXPECT_EQ(0u, video_channel_->send_streams().size());
   1040   EXPECT_EQ(0u, voice_channel_->send_streams().size());
   1041 }
   1042 
   1043 // Test we will return fail when apply an offer that doesn't have
   1044 // crypto enabled.
   1045 TEST_F(WebRtcSessionTest, SetNonCryptoOffer) {
   1046   Init(NULL);
   1047   cricket::MediaSessionOptions options;
   1048   options.has_video = true;
   1049   JsepSessionDescription* offer = CreateRemoteOffer(
   1050       options, cricket::SEC_DISABLED);
   1051   ASSERT_TRUE(offer != NULL);
   1052   VerifyNoCryptoParams(offer->description(), false);
   1053   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1054   // the offer.
   1055   SetRemoteDescriptionExpectError(kSdpWithoutCrypto, offer);
   1056   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
   1057   ASSERT_TRUE(offer != NULL);
   1058   SetLocalDescriptionExpectError(kSdpWithoutCrypto, offer);
   1059 }
   1060 
   1061 // Test we will return fail when apply an answer that doesn't have
   1062 // crypto enabled.
   1063 TEST_F(WebRtcSessionTest, SetLocalNonCryptoAnswer) {
   1064   Init(NULL);
   1065   SessionDescriptionInterface* offer = NULL;
   1066   SessionDescriptionInterface* answer = NULL;
   1067   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
   1068   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1069   // the offer.
   1070   SetRemoteDescriptionWithoutError(offer);
   1071   SetLocalDescriptionExpectError(kSdpWithoutCrypto, answer);
   1072 }
   1073 
   1074 // Test we will return fail when apply an answer that doesn't have
   1075 // crypto enabled.
   1076 TEST_F(WebRtcSessionTest, SetRemoteNonCryptoAnswer) {
   1077   Init(NULL);
   1078   SessionDescriptionInterface* offer = NULL;
   1079   SessionDescriptionInterface* answer = NULL;
   1080   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
   1081   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1082   // the offer.
   1083   SetLocalDescriptionWithoutError(offer);
   1084   SetRemoteDescriptionExpectError(kSdpWithoutCrypto, answer);
   1085 }
   1086 
   1087 // Test that we can create and set an offer with a DTLS fingerprint.
   1088 TEST_F(WebRtcSessionTest, CreateSetDtlsOffer) {
   1089   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   1090   InitWithDtls();
   1091   mediastream_signaling_.SendAudioVideoStream1();
   1092   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1093   ASSERT_TRUE(offer != NULL);
   1094   VerifyFingerprintStatus(offer->description(), true);
   1095   // SetLocalDescription will take the ownership of the offer.
   1096   SetLocalDescriptionWithoutError(offer);
   1097 }
   1098 
   1099 // Test that we can process an offer with a DTLS fingerprint
   1100 // and that we return an answer with a fingerprint.
   1101 TEST_F(WebRtcSessionTest, ReceiveDtlsOfferCreateAnswer) {
   1102   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   1103   InitWithDtls();
   1104   SetFactoryDtlsSrtp();
   1105   cricket::MediaSessionOptions options;
   1106   options.has_video = true;
   1107   JsepSessionDescription* offer = CreateRemoteOffer(options);
   1108   ASSERT_TRUE(offer != NULL);
   1109   VerifyFingerprintStatus(offer->description(), true);
   1110 
   1111   // SetRemoteDescription will take the ownership of the offer.
   1112   SetRemoteDescriptionWithoutError(offer);
   1113 
   1114   // Verify that we get a crypto fingerprint in the answer.
   1115   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1116   ASSERT_TRUE(answer != NULL);
   1117   VerifyFingerprintStatus(answer->description(), true);
   1118   // Check that we don't have an a=crypto line in the answer.
   1119   VerifyNoCryptoParams(answer->description(), true);
   1120 
   1121   // Now set the local description, which should work, even without a=crypto.
   1122   SetLocalDescriptionWithoutError(answer);
   1123 }
   1124 
   1125 // Test that even if we support DTLS, if the other side didn't offer a
   1126 // fingerprint, we don't either.
   1127 TEST_F(WebRtcSessionTest, ReceiveNoDtlsOfferCreateAnswer) {
   1128   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   1129   InitWithDtls();
   1130   cricket::MediaSessionOptions options;
   1131   options.has_video = true;
   1132   JsepSessionDescription* offer = CreateRemoteOffer(
   1133       options, cricket::SEC_REQUIRED);
   1134   ASSERT_TRUE(offer != NULL);
   1135   VerifyFingerprintStatus(offer->description(), false);
   1136 
   1137   // SetRemoteDescription will take the ownership of
   1138   // the offer.
   1139   SetRemoteDescriptionWithoutError(offer);
   1140 
   1141   // Verify that we don't get a crypto fingerprint in the answer.
   1142   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1143   ASSERT_TRUE(answer != NULL);
   1144   VerifyFingerprintStatus(answer->description(), false);
   1145 
   1146   // Now set the local description.
   1147   SetLocalDescriptionWithoutError(answer);
   1148 }
   1149 
   1150 TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
   1151   Init(NULL);
   1152   mediastream_signaling_.SendNothing();
   1153   // SetLocalDescription take ownership of offer.
   1154   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1155   SetLocalDescriptionWithoutError(offer);
   1156 
   1157   // SetLocalDescription take ownership of offer.
   1158   SessionDescriptionInterface* offer2 = CreateOffer(NULL);
   1159   SetLocalDescriptionWithoutError(offer2);
   1160 }
   1161 
   1162 TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
   1163   Init(NULL);
   1164   mediastream_signaling_.SendNothing();
   1165   // SetLocalDescription take ownership of offer.
   1166   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1167   SetRemoteDescriptionWithoutError(offer);
   1168 
   1169   SessionDescriptionInterface* offer2 = CreateOffer(NULL);
   1170   SetRemoteDescriptionWithoutError(offer2);
   1171 }
   1172 
   1173 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
   1174   Init(NULL);
   1175   mediastream_signaling_.SendNothing();
   1176   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1177   SetLocalDescriptionWithoutError(offer);
   1178   offer = CreateOffer(NULL);
   1179   SetRemoteDescriptionExpectError(
   1180       "Called with type in wrong state, type: offer state: STATE_SENTINITIATE",
   1181       offer);
   1182 }
   1183 
   1184 TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
   1185   Init(NULL);
   1186   mediastream_signaling_.SendNothing();
   1187   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1188   SetRemoteDescriptionWithoutError(offer);
   1189   offer = CreateOffer(NULL);
   1190   SetLocalDescriptionExpectError(
   1191       "Called with type in wrong state, type: "
   1192       "offer state: STATE_RECEIVEDINITIATE",
   1193       offer);
   1194 }
   1195 
   1196 TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
   1197   Init(NULL);
   1198   mediastream_signaling_.SendNothing();
   1199   SessionDescriptionInterface* offer = CreateRemoteOffer();
   1200   SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
   1201 
   1202   JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
   1203       CreateAnswer(NULL));
   1204   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
   1205   SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
   1206 
   1207   mediastream_signaling_.SendAudioVideoStream1();
   1208   JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
   1209       CreateAnswer(NULL));
   1210   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
   1211 
   1212   SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
   1213 
   1214   mediastream_signaling_.SendAudioVideoStream2();
   1215   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1216   SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
   1217 }
   1218 
   1219 TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
   1220   Init(NULL);
   1221   mediastream_signaling_.SendNothing();
   1222   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1223   SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
   1224 
   1225   JsepSessionDescription* pranswer =
   1226       CreateRemoteAnswer(session_->local_description());
   1227   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
   1228 
   1229   SetRemoteDescriptionExpectState(pranswer,
   1230                                   BaseSession::STATE_RECEIVEDPRACCEPT);
   1231 
   1232   mediastream_signaling_.SendAudioVideoStream1();
   1233   JsepSessionDescription* pranswer2 =
   1234       CreateRemoteAnswer(session_->local_description());
   1235   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
   1236 
   1237   SetRemoteDescriptionExpectState(pranswer2,
   1238                                   BaseSession::STATE_RECEIVEDPRACCEPT);
   1239 
   1240   mediastream_signaling_.SendAudioVideoStream2();
   1241   SessionDescriptionInterface* answer =
   1242       CreateRemoteAnswer(session_->local_description());
   1243   SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
   1244 }
   1245 
   1246 TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
   1247   Init(NULL);
   1248   mediastream_signaling_.SendNothing();
   1249   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1250       CreateOffer(NULL));
   1251   SessionDescriptionInterface* answer =
   1252       CreateRemoteAnswer(offer.get());
   1253   SetLocalDescriptionExpectError(
   1254       "Called with type in wrong state, type: answer state: STATE_INIT",
   1255       answer);
   1256 }
   1257 
   1258 TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
   1259   Init(NULL);
   1260   mediastream_signaling_.SendNothing();
   1261   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1262         CreateOffer(NULL));
   1263   SessionDescriptionInterface* answer =
   1264       CreateRemoteAnswer(offer.get());
   1265   SetRemoteDescriptionExpectError(
   1266       "Called with type in wrong state, type: answer state: STATE_INIT",
   1267       answer);
   1268 }
   1269 
   1270 TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
   1271   Init(NULL);
   1272   mediastream_signaling_.SendAudioVideoStream1();
   1273 
   1274   cricket::Candidate candidate;
   1275   candidate.set_component(1);
   1276   JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
   1277 
   1278   // Fail since we have not set a offer description.
   1279   EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
   1280 
   1281   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1282   SetLocalDescriptionWithoutError(offer);
   1283   // Candidate should be allowed to add before remote description.
   1284   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
   1285   candidate.set_component(2);
   1286   JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
   1287   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
   1288 
   1289   SessionDescriptionInterface* answer = CreateRemoteAnswer(
   1290       session_->local_description());
   1291   SetRemoteDescriptionWithoutError(answer);
   1292 
   1293   // Verifying the candidates are copied properly from internal vector.
   1294   const SessionDescriptionInterface* remote_desc =
   1295       session_->remote_description();
   1296   ASSERT_TRUE(remote_desc != NULL);
   1297   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   1298   const IceCandidateCollection* candidates =
   1299       remote_desc->candidates(kMediaContentIndex0);
   1300   ASSERT_EQ(2u, candidates->count());
   1301   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   1302   EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
   1303   EXPECT_EQ(1, candidates->at(0)->candidate().component());
   1304   EXPECT_EQ(2, candidates->at(1)->candidate().component());
   1305 
   1306   candidate.set_component(2);
   1307   JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
   1308   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
   1309   ASSERT_EQ(3u, candidates->count());
   1310 
   1311   JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
   1312   EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
   1313 }
   1314 
   1315 // Test that a remote candidate is added to the remote session description and
   1316 // that it is retained if the remote session description is changed.
   1317 TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
   1318   Init(NULL);
   1319   cricket::Candidate candidate1;
   1320   candidate1.set_component(1);
   1321   JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
   1322                                   candidate1);
   1323   mediastream_signaling_.SendAudioVideoStream1();
   1324   CreateAndSetRemoteOfferAndLocalAnswer();
   1325 
   1326   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
   1327   const SessionDescriptionInterface* remote_desc =
   1328       session_->remote_description();
   1329   ASSERT_TRUE(remote_desc != NULL);
   1330   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   1331   const IceCandidateCollection* candidates =
   1332       remote_desc->candidates(kMediaContentIndex0);
   1333   ASSERT_EQ(1u, candidates->count());
   1334   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   1335 
   1336   // Update the RemoteSessionDescription with a new session description and
   1337   // a candidate and check that the new remote session description contains both
   1338   // candidates.
   1339   SessionDescriptionInterface* offer = CreateRemoteOffer();
   1340   cricket::Candidate candidate2;
   1341   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
   1342                                   candidate2);
   1343   EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
   1344   SetRemoteDescriptionWithoutError(offer);
   1345 
   1346   remote_desc = session_->remote_description();
   1347   ASSERT_TRUE(remote_desc != NULL);
   1348   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   1349   candidates = remote_desc->candidates(kMediaContentIndex0);
   1350   ASSERT_EQ(2u, candidates->count());
   1351   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   1352   // Username and password have be updated with the TransportInfo of the
   1353   // SessionDescription, won't be equal to the original one.
   1354   candidate2.set_username(candidates->at(0)->candidate().username());
   1355   candidate2.set_password(candidates->at(0)->candidate().password());
   1356   EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
   1357   EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
   1358   // No need to verify the username and password.
   1359   candidate1.set_username(candidates->at(1)->candidate().username());
   1360   candidate1.set_password(candidates->at(1)->candidate().password());
   1361   EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
   1362 
   1363   // Test that the candidate is ignored if we can add the same candidate again.
   1364   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
   1365 }
   1366 
   1367 // Test that local candidates are added to the local session description and
   1368 // that they are retained if the local session description is changed.
   1369 TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
   1370   AddInterface(kClientAddr1);
   1371   Init(NULL);
   1372   mediastream_signaling_.SendAudioVideoStream1();
   1373   CreateAndSetRemoteOfferAndLocalAnswer();
   1374 
   1375   const SessionDescriptionInterface* local_desc = session_->local_description();
   1376   const IceCandidateCollection* candidates =
   1377       local_desc->candidates(kMediaContentIndex0);
   1378   ASSERT_TRUE(candidates != NULL);
   1379   EXPECT_EQ(0u, candidates->count());
   1380 
   1381   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1382 
   1383   local_desc = session_->local_description();
   1384   candidates = local_desc->candidates(kMediaContentIndex0);
   1385   ASSERT_TRUE(candidates != NULL);
   1386   EXPECT_LT(0u, candidates->count());
   1387   candidates = local_desc->candidates(1);
   1388   ASSERT_TRUE(candidates != NULL);
   1389   EXPECT_LT(0u, candidates->count());
   1390 
   1391   // Update the session descriptions.
   1392   mediastream_signaling_.SendAudioVideoStream1();
   1393   CreateAndSetRemoteOfferAndLocalAnswer();
   1394 
   1395   local_desc = session_->local_description();
   1396   candidates = local_desc->candidates(kMediaContentIndex0);
   1397   ASSERT_TRUE(candidates != NULL);
   1398   EXPECT_LT(0u, candidates->count());
   1399   candidates = local_desc->candidates(1);
   1400   ASSERT_TRUE(candidates != NULL);
   1401   EXPECT_LT(0u, candidates->count());
   1402 }
   1403 
   1404 // Test that we can set a remote session description with remote candidates.
   1405 TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
   1406   Init(NULL);
   1407 
   1408   cricket::Candidate candidate1;
   1409   candidate1.set_component(1);
   1410   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
   1411                                  candidate1);
   1412   mediastream_signaling_.SendAudioVideoStream1();
   1413   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1414 
   1415   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   1416   SetRemoteDescriptionWithoutError(offer);
   1417 
   1418   const SessionDescriptionInterface* remote_desc =
   1419       session_->remote_description();
   1420   ASSERT_TRUE(remote_desc != NULL);
   1421   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   1422   const IceCandidateCollection* candidates =
   1423       remote_desc->candidates(kMediaContentIndex0);
   1424   ASSERT_EQ(1u, candidates->count());
   1425   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   1426 
   1427   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1428   SetLocalDescriptionWithoutError(answer);
   1429 }
   1430 
   1431 // Test that offers and answers contains ice candidates when Ice candidates have
   1432 // been gathered.
   1433 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
   1434   AddInterface(kClientAddr1);
   1435   Init(NULL);
   1436   mediastream_signaling_.SendAudioVideoStream1();
   1437   // Ice is started but candidates are not provided until SetLocalDescription
   1438   // is called.
   1439   EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
   1440   EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
   1441   CreateAndSetRemoteOfferAndLocalAnswer();
   1442   // Wait until at least one local candidate has been collected.
   1443   EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
   1444                    kIceCandidatesTimeout);
   1445   EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
   1446                    kIceCandidatesTimeout);
   1447 
   1448   talk_base::scoped_ptr<SessionDescriptionInterface> local_offer(
   1449       CreateOffer(NULL));
   1450   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
   1451   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
   1452   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
   1453   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
   1454 
   1455   SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
   1456   SetRemoteDescriptionWithoutError(remote_offer);
   1457   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1458   ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
   1459   EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
   1460   ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
   1461   EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
   1462   SetLocalDescriptionWithoutError(answer);
   1463 }
   1464 
   1465 // Verifies TransportProxy and media channels are created with content names
   1466 // present in the SessionDescription.
   1467 TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
   1468   Init(NULL);
   1469   mediastream_signaling_.SendAudioVideoStream1();
   1470   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1471       CreateOffer(NULL));
   1472 
   1473   // CreateOffer creates session description with the content names "audio" and
   1474   // "video". Goal is to modify these content names and verify transport channel
   1475   // proxy in the BaseSession, as proxies are created with the content names
   1476   // present in SDP.
   1477   std::string sdp;
   1478   EXPECT_TRUE(offer->ToString(&sdp));
   1479   const std::string kAudioMid = "a=mid:audio";
   1480   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
   1481   const std::string kVideoMid = "a=mid:video";
   1482   const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
   1483 
   1484   // Replacing |audio| with |audio_content_name|.
   1485   talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
   1486                              kAudioMidReplaceStr.c_str(),
   1487                              kAudioMidReplaceStr.length(),
   1488                              &sdp);
   1489   // Replacing |video| with |video_content_name|.
   1490   talk_base::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
   1491                              kVideoMidReplaceStr.c_str(),
   1492                              kVideoMidReplaceStr.length(),
   1493                              &sdp);
   1494 
   1495   SessionDescriptionInterface* modified_offer =
   1496       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   1497 
   1498   SetRemoteDescriptionWithoutError(modified_offer);
   1499 
   1500   SessionDescriptionInterface* answer =
   1501       CreateAnswer(NULL);
   1502   SetLocalDescriptionWithoutError(answer);
   1503 
   1504   EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
   1505   EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
   1506   EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
   1507   EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
   1508 }
   1509 
   1510 // Test that an offer contains the correct media content descriptions based on
   1511 // the send streams when no constraints have been set.
   1512 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
   1513   Init(NULL);
   1514   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1515       CreateOffer(NULL));
   1516   ASSERT_TRUE(offer != NULL);
   1517   const cricket::ContentInfo* content =
   1518       cricket::GetFirstAudioContent(offer->description());
   1519   EXPECT_TRUE(content != NULL);
   1520   content = cricket::GetFirstVideoContent(offer->description());
   1521   EXPECT_TRUE(content == NULL);
   1522 }
   1523 
   1524 // Test that an offer contains the correct media content descriptions based on
   1525 // the send streams when no constraints have been set.
   1526 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
   1527   Init(NULL);
   1528   // Test Audio only offer.
   1529   mediastream_signaling_.UseOptionsAudioOnly();
   1530   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1531         CreateOffer(NULL));
   1532   const cricket::ContentInfo* content =
   1533       cricket::GetFirstAudioContent(offer->description());
   1534   EXPECT_TRUE(content != NULL);
   1535   content = cricket::GetFirstVideoContent(offer->description());
   1536   EXPECT_TRUE(content == NULL);
   1537 
   1538   // Test Audio / Video offer.
   1539   mediastream_signaling_.SendAudioVideoStream1();
   1540   offer.reset(CreateOffer(NULL));
   1541   content = cricket::GetFirstAudioContent(offer->description());
   1542   EXPECT_TRUE(content != NULL);
   1543   content = cricket::GetFirstVideoContent(offer->description());
   1544   EXPECT_TRUE(content != NULL);
   1545 }
   1546 
   1547 // Test that an offer contains no media content descriptions if
   1548 // kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
   1549 TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
   1550   Init(NULL);
   1551   webrtc::FakeConstraints constraints_no_receive;
   1552   constraints_no_receive.SetMandatoryReceiveAudio(false);
   1553   constraints_no_receive.SetMandatoryReceiveVideo(false);
   1554 
   1555   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1556       CreateOffer(&constraints_no_receive));
   1557   ASSERT_TRUE(offer != NULL);
   1558   const cricket::ContentInfo* content =
   1559       cricket::GetFirstAudioContent(offer->description());
   1560   EXPECT_TRUE(content == NULL);
   1561   content = cricket::GetFirstVideoContent(offer->description());
   1562   EXPECT_TRUE(content == NULL);
   1563 }
   1564 
   1565 // Test that an offer contains only audio media content descriptions if
   1566 // kOfferToReceiveAudio constraints are set to true.
   1567 TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
   1568   Init(NULL);
   1569   webrtc::FakeConstraints constraints_audio_only;
   1570   constraints_audio_only.SetMandatoryReceiveAudio(true);
   1571   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1572         CreateOffer(&constraints_audio_only));
   1573 
   1574   const cricket::ContentInfo* content =
   1575       cricket::GetFirstAudioContent(offer->description());
   1576   EXPECT_TRUE(content != NULL);
   1577   content = cricket::GetFirstVideoContent(offer->description());
   1578   EXPECT_TRUE(content == NULL);
   1579 }
   1580 
   1581 // Test that an offer contains audio and video media content descriptions if
   1582 // kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
   1583 TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
   1584   Init(NULL);
   1585   // Test Audio / Video offer.
   1586   webrtc::FakeConstraints constraints_audio_video;
   1587   constraints_audio_video.SetMandatoryReceiveAudio(true);
   1588   constraints_audio_video.SetMandatoryReceiveVideo(true);
   1589   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1590       CreateOffer(&constraints_audio_video));
   1591   const cricket::ContentInfo* content =
   1592       cricket::GetFirstAudioContent(offer->description());
   1593 
   1594   EXPECT_TRUE(content != NULL);
   1595   content = cricket::GetFirstVideoContent(offer->description());
   1596   EXPECT_TRUE(content != NULL);
   1597 
   1598   // TODO(perkj): Should the direction be set to SEND_ONLY if
   1599   // The constraints is set to not receive audio or video but a track is added?
   1600 }
   1601 
   1602 // Test that an answer can not be created if the last remote description is not
   1603 // an offer.
   1604 TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
   1605   Init(NULL);
   1606   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1607   SetLocalDescriptionWithoutError(offer);
   1608   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   1609   SetRemoteDescriptionWithoutError(answer);
   1610   EXPECT_TRUE(CreateAnswer(NULL) == NULL);
   1611 }
   1612 
   1613 // Test that an answer contains the correct media content descriptions when no
   1614 // constraints have been set.
   1615 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
   1616   Init(NULL);
   1617   // Create a remote offer with audio and video content.
   1618   talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   1619   SetRemoteDescriptionWithoutError(offer.release());
   1620   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1621       CreateAnswer(NULL));
   1622   const cricket::ContentInfo* content =
   1623       cricket::GetFirstAudioContent(answer->description());
   1624   ASSERT_TRUE(content != NULL);
   1625   EXPECT_FALSE(content->rejected);
   1626 
   1627   content = cricket::GetFirstVideoContent(answer->description());
   1628   ASSERT_TRUE(content != NULL);
   1629   EXPECT_FALSE(content->rejected);
   1630 }
   1631 
   1632 // Test that an answer contains the correct media content descriptions when no
   1633 // constraints have been set and the offer only contain audio.
   1634 TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
   1635   Init(NULL);
   1636   // Create a remote offer with audio only.
   1637   cricket::MediaSessionOptions options;
   1638   options.has_audio = true;
   1639   options.has_video = false;
   1640   talk_base::scoped_ptr<JsepSessionDescription> offer(
   1641       CreateRemoteOffer(options));
   1642   ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
   1643   ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
   1644 
   1645   SetRemoteDescriptionWithoutError(offer.release());
   1646   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1647       CreateAnswer(NULL));
   1648   const cricket::ContentInfo* content =
   1649       cricket::GetFirstAudioContent(answer->description());
   1650   ASSERT_TRUE(content != NULL);
   1651   EXPECT_FALSE(content->rejected);
   1652 
   1653   EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
   1654 }
   1655 
   1656 // Test that an answer contains the correct media content descriptions when no
   1657 // constraints have been set.
   1658 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
   1659   Init(NULL);
   1660   // Create a remote offer with audio and video content.
   1661   talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   1662   SetRemoteDescriptionWithoutError(offer.release());
   1663   // Test with a stream with tracks.
   1664   mediastream_signaling_.SendAudioVideoStream1();
   1665   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1666       CreateAnswer(NULL));
   1667   const cricket::ContentInfo* content =
   1668       cricket::GetFirstAudioContent(answer->description());
   1669   ASSERT_TRUE(content != NULL);
   1670   EXPECT_FALSE(content->rejected);
   1671 
   1672   content = cricket::GetFirstVideoContent(answer->description());
   1673   ASSERT_TRUE(content != NULL);
   1674   EXPECT_FALSE(content->rejected);
   1675 }
   1676 
   1677 // Test that an answer contains the correct media content descriptions when
   1678 // constraints have been set but no stream is sent.
   1679 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
   1680   Init(NULL);
   1681   // Create a remote offer with audio and video content.
   1682   talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   1683   SetRemoteDescriptionWithoutError(offer.release());
   1684 
   1685   webrtc::FakeConstraints constraints_no_receive;
   1686   constraints_no_receive.SetMandatoryReceiveAudio(false);
   1687   constraints_no_receive.SetMandatoryReceiveVideo(false);
   1688 
   1689   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1690       CreateAnswer(&constraints_no_receive));
   1691   const cricket::ContentInfo* content =
   1692       cricket::GetFirstAudioContent(answer->description());
   1693   ASSERT_TRUE(content != NULL);
   1694   EXPECT_TRUE(content->rejected);
   1695 
   1696   content = cricket::GetFirstVideoContent(answer->description());
   1697   ASSERT_TRUE(content != NULL);
   1698   EXPECT_TRUE(content->rejected);
   1699 }
   1700 
   1701 // Test that an answer contains the correct media content descriptions when
   1702 // constraints have been set and streams are sent.
   1703 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
   1704   Init(NULL);
   1705   // Create a remote offer with audio and video content.
   1706   talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   1707   SetRemoteDescriptionWithoutError(offer.release());
   1708 
   1709   webrtc::FakeConstraints constraints_no_receive;
   1710   constraints_no_receive.SetMandatoryReceiveAudio(false);
   1711   constraints_no_receive.SetMandatoryReceiveVideo(false);
   1712 
   1713   // Test with a stream with tracks.
   1714   mediastream_signaling_.SendAudioVideoStream1();
   1715   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1716       CreateAnswer(&constraints_no_receive));
   1717 
   1718   // TODO(perkj): Should the direction be set to SEND_ONLY?
   1719   const cricket::ContentInfo* content =
   1720       cricket::GetFirstAudioContent(answer->description());
   1721   ASSERT_TRUE(content != NULL);
   1722   EXPECT_FALSE(content->rejected);
   1723 
   1724   // TODO(perkj): Should the direction be set to SEND_ONLY?
   1725   content = cricket::GetFirstVideoContent(answer->description());
   1726   ASSERT_TRUE(content != NULL);
   1727   EXPECT_FALSE(content->rejected);
   1728 }
   1729 
   1730 TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
   1731   AddCNCodecs();
   1732   Init(NULL);
   1733   webrtc::FakeConstraints constraints;
   1734   constraints.SetOptionalVAD(false);
   1735   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1736       CreateOffer(&constraints));
   1737   const cricket::ContentInfo* content =
   1738       cricket::GetFirstAudioContent(offer->description());
   1739   EXPECT_TRUE(content != NULL);
   1740   EXPECT_TRUE(VerifyNoCNCodecs(content));
   1741 }
   1742 
   1743 TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
   1744   AddCNCodecs();
   1745   Init(NULL);
   1746   // Create a remote offer with audio and video content.
   1747   talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   1748   SetRemoteDescriptionWithoutError(offer.release());
   1749 
   1750   webrtc::FakeConstraints constraints;
   1751   constraints.SetOptionalVAD(false);
   1752   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1753       CreateAnswer(&constraints));
   1754   const cricket::ContentInfo* content =
   1755       cricket::GetFirstAudioContent(answer->description());
   1756   ASSERT_TRUE(content != NULL);
   1757   EXPECT_TRUE(VerifyNoCNCodecs(content));
   1758 }
   1759 
   1760 // This test verifies the call setup when remote answer with audio only and
   1761 // later updates with video.
   1762 TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
   1763   Init(NULL);
   1764   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
   1765   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
   1766 
   1767   mediastream_signaling_.SendAudioVideoStream1();
   1768   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1769 
   1770   cricket::MediaSessionOptions options;
   1771   options.has_video = false;
   1772   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
   1773 
   1774   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
   1775   // and answer;
   1776   SetLocalDescriptionWithoutError(offer);
   1777   SetRemoteDescriptionWithoutError(answer);
   1778 
   1779   video_channel_ = media_engine_->GetVideoChannel(0);
   1780   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1781 
   1782   ASSERT_TRUE(video_channel_ == NULL);
   1783 
   1784   ASSERT_EQ(0u, voice_channel_->recv_streams().size());
   1785   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1786   EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
   1787 
   1788   // Let the remote end update the session descriptions, with Audio and Video.
   1789   mediastream_signaling_.SendAudioVideoStream2();
   1790   CreateAndSetRemoteOfferAndLocalAnswer();
   1791 
   1792   video_channel_ = media_engine_->GetVideoChannel(0);
   1793   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1794 
   1795   ASSERT_TRUE(video_channel_ != NULL);
   1796   ASSERT_TRUE(voice_channel_ != NULL);
   1797 
   1798   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1799   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1800   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
   1801   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
   1802   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1803   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1804   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   1805   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   1806 
   1807   // Change session back to audio only.
   1808   mediastream_signaling_.UseOptionsAudioOnly();
   1809   CreateAndSetRemoteOfferAndLocalAnswer();
   1810 
   1811   EXPECT_EQ(0u, video_channel_->recv_streams().size());
   1812   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1813   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   1814   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1815   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   1816 }
   1817 
   1818 // This test verifies the call setup when remote answer with video only and
   1819 // later updates with audio.
   1820 TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
   1821   Init(NULL);
   1822   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
   1823   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
   1824   mediastream_signaling_.SendAudioVideoStream1();
   1825   SessionDescriptionInterface* offer = CreateOffer(NULL);
   1826 
   1827   cricket::MediaSessionOptions options;
   1828   options.has_audio = false;
   1829   options.has_video = true;
   1830   SessionDescriptionInterface* answer = CreateRemoteAnswer(
   1831       offer, options, cricket::SEC_ENABLED);
   1832 
   1833   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
   1834   // and answer.
   1835   SetLocalDescriptionWithoutError(offer);
   1836   SetRemoteDescriptionWithoutError(answer);
   1837 
   1838   video_channel_ = media_engine_->GetVideoChannel(0);
   1839   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1840 
   1841   ASSERT_TRUE(voice_channel_ == NULL);
   1842   ASSERT_TRUE(video_channel_ != NULL);
   1843 
   1844   EXPECT_EQ(0u, video_channel_->recv_streams().size());
   1845   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1846   EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
   1847 
   1848   // Update the session descriptions, with Audio and Video.
   1849   mediastream_signaling_.SendAudioVideoStream2();
   1850   CreateAndSetRemoteOfferAndLocalAnswer();
   1851 
   1852   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1853   ASSERT_TRUE(voice_channel_ != NULL);
   1854 
   1855   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1856   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1857   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   1858   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   1859 
   1860   // Change session back to video only.
   1861   mediastream_signaling_.UseOptionsVideoOnly();
   1862   CreateAndSetRemoteOfferAndLocalAnswer();
   1863 
   1864   video_channel_ = media_engine_->GetVideoChannel(0);
   1865   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1866 
   1867   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1868   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
   1869   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1870   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
   1871 }
   1872 
   1873 TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
   1874   Init(NULL);
   1875   mediastream_signaling_.SendAudioVideoStream1();
   1876   scoped_ptr<SessionDescriptionInterface> offer(
   1877       CreateOffer(NULL));
   1878   VerifyCryptoParams(offer->description());
   1879   SetRemoteDescriptionWithoutError(offer.release());
   1880   scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   1881   VerifyCryptoParams(answer->description());
   1882 }
   1883 
   1884 TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
   1885   Init(NULL);
   1886   session_->set_secure_policy(cricket::SEC_DISABLED);
   1887   mediastream_signaling_.SendAudioVideoStream1();
   1888   scoped_ptr<SessionDescriptionInterface> offer(
   1889         CreateOffer(NULL));
   1890   VerifyNoCryptoParams(offer->description(), false);
   1891 }
   1892 
   1893 TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
   1894   Init(NULL);
   1895   VerifyAnswerFromNonCryptoOffer();
   1896 }
   1897 
   1898 TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
   1899   Init(NULL);
   1900   VerifyAnswerFromCryptoOffer();
   1901 }
   1902 
   1903 TEST_F(WebRtcSessionTest, VerifyBundleFlagInPA) {
   1904   // This test verifies BUNDLE flag in PortAllocator, if BUNDLE information in
   1905   // local description is removed by the application, BUNDLE flag should be
   1906   // disabled in PortAllocator. By default BUNDLE is enabled in the WebRtc.
   1907   Init(NULL);
   1908   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
   1909       cricket::PORTALLOCATOR_ENABLE_BUNDLE);
   1910   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   1911       CreateOffer(NULL));
   1912   cricket::SessionDescription* offer_copy =
   1913       offer->description()->Copy();
   1914   offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   1915   JsepSessionDescription* modified_offer =
   1916       new JsepSessionDescription(JsepSessionDescription::kOffer);
   1917   modified_offer->Initialize(offer_copy, "1", "1");
   1918 
   1919   SetLocalDescriptionWithoutError(modified_offer);
   1920   EXPECT_FALSE(allocator_.flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE);
   1921 }
   1922 
   1923 TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
   1924   Init(NULL);
   1925   mediastream_signaling_.SendAudioVideoStream1();
   1926   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
   1927       cricket::PORTALLOCATOR_ENABLE_BUNDLE);
   1928   FakeConstraints constraints;
   1929   constraints.SetMandatoryUseRtpMux(true);
   1930   SessionDescriptionInterface* offer = CreateOffer(&constraints);
   1931   SetLocalDescriptionWithoutError(offer);
   1932   mediastream_signaling_.SendAudioVideoStream2();
   1933   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   1934       CreateRemoteAnswer(session_->local_description()));
   1935   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   1936   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   1937   JsepSessionDescription* modified_answer =
   1938       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   1939   modified_answer->Initialize(answer_copy, "1", "1");
   1940   SetRemoteDescriptionWithoutError(modified_answer);
   1941   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
   1942       cricket::PORTALLOCATOR_ENABLE_BUNDLE);
   1943 
   1944   video_channel_ = media_engine_->GetVideoChannel(0);
   1945   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1946 
   1947   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1948   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
   1949 
   1950   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1951   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
   1952 
   1953   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1954   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
   1955   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1956   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
   1957 }
   1958 
   1959 // This test verifies that SetLocalDescription and SetRemoteDescription fails
   1960 // if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
   1961 TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
   1962   WebRtcSessionTest::Init(NULL);
   1963   mediastream_signaling_.SendAudioVideoStream1();
   1964   EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
   1965       cricket::PORTALLOCATOR_ENABLE_BUNDLE);
   1966   FakeConstraints constraints;
   1967   constraints.SetMandatoryUseRtpMux(true);
   1968   SessionDescriptionInterface* offer = CreateOffer(&constraints);
   1969   std::string offer_str;
   1970   offer->ToString(&offer_str);
   1971   // Disable rtcp-mux
   1972   const std::string rtcp_mux = "rtcp-mux";
   1973   const std::string xrtcp_mux = "xrtcp-mux";
   1974   talk_base::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
   1975                              xrtcp_mux.c_str(), xrtcp_mux.length(),
   1976                              &offer_str);
   1977   JsepSessionDescription *local_offer =
   1978       new JsepSessionDescription(JsepSessionDescription::kOffer);
   1979   EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
   1980   SetLocalDescriptionExpectError(kBundleWithoutRtcpMux, local_offer);
   1981   JsepSessionDescription *remote_offer =
   1982       new JsepSessionDescription(JsepSessionDescription::kOffer);
   1983   EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
   1984   SetRemoteDescriptionExpectError(kBundleWithoutRtcpMux, remote_offer);
   1985   // Trying unmodified SDP.
   1986   SetLocalDescriptionWithoutError(offer);
   1987 }
   1988 
   1989 TEST_F(WebRtcSessionTest, SetAudioPlayout) {
   1990   Init(NULL);
   1991   mediastream_signaling_.SendAudioVideoStream1();
   1992   CreateAndSetRemoteOfferAndLocalAnswer();
   1993   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   1994   ASSERT_TRUE(channel != NULL);
   1995   ASSERT_EQ(1u, channel->recv_streams().size());
   1996   uint32 receive_ssrc  = channel->recv_streams()[0].first_ssrc();
   1997   double left_vol, right_vol;
   1998   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
   1999   EXPECT_EQ(1, left_vol);
   2000   EXPECT_EQ(1, right_vol);
   2001   talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   2002   session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
   2003   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
   2004   EXPECT_EQ(0, left_vol);
   2005   EXPECT_EQ(0, right_vol);
   2006   EXPECT_EQ(0, renderer->channel_id());
   2007   session_->SetAudioPlayout(receive_ssrc, true, NULL);
   2008   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
   2009   EXPECT_EQ(1, left_vol);
   2010   EXPECT_EQ(1, right_vol);
   2011   EXPECT_EQ(-1, renderer->channel_id());
   2012 }
   2013 
   2014 TEST_F(WebRtcSessionTest, SetAudioSend) {
   2015   Init(NULL);
   2016   mediastream_signaling_.SendAudioVideoStream1();
   2017   CreateAndSetRemoteOfferAndLocalAnswer();
   2018   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   2019   ASSERT_TRUE(channel != NULL);
   2020   ASSERT_EQ(1u, channel->send_streams().size());
   2021   uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
   2022   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   2023 
   2024   cricket::AudioOptions options;
   2025   options.echo_cancellation.Set(true);
   2026 
   2027   talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   2028   session_->SetAudioSend(send_ssrc, false, options, renderer.get());
   2029   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
   2030   EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
   2031   EXPECT_EQ(0, renderer->channel_id());
   2032 
   2033   session_->SetAudioSend(send_ssrc, true, options, NULL);
   2034   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   2035   bool value;
   2036   EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
   2037   EXPECT_TRUE(value);
   2038   EXPECT_EQ(-1, renderer->channel_id());
   2039 }
   2040 
   2041 TEST_F(WebRtcSessionTest, SetVideoPlayout) {
   2042   Init(NULL);
   2043   mediastream_signaling_.SendAudioVideoStream1();
   2044   CreateAndSetRemoteOfferAndLocalAnswer();
   2045   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
   2046   ASSERT_TRUE(channel != NULL);
   2047   ASSERT_LT(0u, channel->renderers().size());
   2048   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
   2049   ASSERT_EQ(1u, channel->recv_streams().size());
   2050   uint32 receive_ssrc  = channel->recv_streams()[0].first_ssrc();
   2051   cricket::FakeVideoRenderer renderer;
   2052   session_->SetVideoPlayout(receive_ssrc, true, &renderer);
   2053   EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
   2054   session_->SetVideoPlayout(receive_ssrc, false, &renderer);
   2055   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
   2056 }
   2057 
   2058 TEST_F(WebRtcSessionTest, SetVideoSend) {
   2059   Init(NULL);
   2060   mediastream_signaling_.SendAudioVideoStream1();
   2061   CreateAndSetRemoteOfferAndLocalAnswer();
   2062   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
   2063   ASSERT_TRUE(channel != NULL);
   2064   ASSERT_EQ(1u, channel->send_streams().size());
   2065   uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
   2066   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   2067   cricket::VideoOptions* options = NULL;
   2068   session_->SetVideoSend(send_ssrc, false, options);
   2069   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
   2070   session_->SetVideoSend(send_ssrc, true, options);
   2071   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   2072 }
   2073 
   2074 TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
   2075   TestCanInsertDtmf(false);
   2076 }
   2077 
   2078 TEST_F(WebRtcSessionTest, CanInsertDtmf) {
   2079   TestCanInsertDtmf(true);
   2080 }
   2081 
   2082 TEST_F(WebRtcSessionTest, InsertDtmf) {
   2083   // Setup
   2084   Init(NULL);
   2085   mediastream_signaling_.SendAudioVideoStream1();
   2086   CreateAndSetRemoteOfferAndLocalAnswer();
   2087   FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   2088   EXPECT_EQ(0U, channel->dtmf_info_queue().size());
   2089 
   2090   // Insert DTMF
   2091   const int expected_flags = DF_SEND;
   2092   const int expected_duration = 90;
   2093   session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
   2094   session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
   2095   session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
   2096 
   2097   // Verify
   2098   ASSERT_EQ(3U, channel->dtmf_info_queue().size());
   2099   const uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
   2100   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
   2101                               expected_duration, expected_flags));
   2102   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
   2103                               expected_duration, expected_flags));
   2104   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
   2105                               expected_duration, expected_flags));
   2106 }
   2107 
   2108 // This test verifies the |initiator| flag when session initiates the call.
   2109 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
   2110   Init(NULL);
   2111   EXPECT_FALSE(session_->initiator());
   2112   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2113   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   2114   SetLocalDescriptionWithoutError(offer);
   2115   EXPECT_TRUE(session_->initiator());
   2116   SetRemoteDescriptionWithoutError(answer);
   2117   EXPECT_TRUE(session_->initiator());
   2118 }
   2119 
   2120 // This test verifies the |initiator| flag when session receives the call.
   2121 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
   2122   Init(NULL);
   2123   EXPECT_FALSE(session_->initiator());
   2124   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2125   SetRemoteDescriptionWithoutError(offer);
   2126   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2127 
   2128   EXPECT_FALSE(session_->initiator());
   2129   SetLocalDescriptionWithoutError(answer);
   2130   EXPECT_FALSE(session_->initiator());
   2131 }
   2132 
   2133 // This test verifies the ice protocol type at initiator of the call
   2134 // if |a=ice-options:google-ice| is present in answer.
   2135 TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
   2136   Init(NULL);
   2137   mediastream_signaling_.SendAudioVideoStream1();
   2138   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2139   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   2140       CreateRemoteAnswer(offer));
   2141   SetLocalDescriptionWithoutError(offer);
   2142   std::string sdp;
   2143   EXPECT_TRUE(answer->ToString(&sdp));
   2144   // Adding ice-options to the session level.
   2145   InjectAfter("t=0 0\r\n",
   2146               "a=ice-options:google-ice\r\n",
   2147               &sdp);
   2148   SessionDescriptionInterface* answer_with_gice =
   2149       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   2150   SetRemoteDescriptionWithoutError(answer_with_gice);
   2151   VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
   2152   VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
   2153 }
   2154 
   2155 // This test verifies the ice protocol type at initiator of the call
   2156 // if ICE RFC5245 is supported in answer.
   2157 TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
   2158   Init(NULL);
   2159   mediastream_signaling_.SendAudioVideoStream1();
   2160   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2161   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   2162   SetLocalDescriptionWithoutError(offer);
   2163 
   2164   SetRemoteDescriptionWithoutError(answer);
   2165   VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
   2166   VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
   2167 }
   2168 
   2169 // This test verifies the ice protocol type at receiver side of the call if
   2170 // receiver decides to use google-ice.
   2171 TEST_F(WebRtcSessionTest, TestReceiverGIceInOffer) {
   2172   Init(NULL);
   2173   mediastream_signaling_.SendAudioVideoStream1();
   2174   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2175   SetRemoteDescriptionWithoutError(offer);
   2176   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   2177       CreateAnswer(NULL));
   2178   std::string sdp;
   2179   EXPECT_TRUE(answer->ToString(&sdp));
   2180   // Adding ice-options to the session level.
   2181   InjectAfter("t=0 0\r\n",
   2182               "a=ice-options:google-ice\r\n",
   2183               &sdp);
   2184   SessionDescriptionInterface* answer_with_gice =
   2185       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   2186   SetLocalDescriptionWithoutError(answer_with_gice);
   2187   VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
   2188   VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
   2189 }
   2190 
   2191 // This test verifies the ice protocol type at receiver side of the call if
   2192 // receiver decides to use ice RFC 5245.
   2193 TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
   2194   Init(NULL);
   2195   mediastream_signaling_.SendAudioVideoStream1();
   2196   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2197   SetRemoteDescriptionWithoutError(offer);
   2198   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2199   SetLocalDescriptionWithoutError(answer);
   2200   VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
   2201   VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
   2202 }
   2203 
   2204 // This test verifies the session state when ICE RFC5245 in offer and
   2205 // ICE google-ice in answer.
   2206 TEST_F(WebRtcSessionTest, TestIceOfferGIceOnlyAnswer) {
   2207   Init(NULL);
   2208   mediastream_signaling_.SendAudioVideoStream1();
   2209   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   2210       CreateOffer(NULL));
   2211   std::string offer_str;
   2212   offer->ToString(&offer_str);
   2213   // Disable google-ice
   2214   const std::string gice_option = "google-ice";
   2215   const std::string xgoogle_xice = "xgoogle-xice";
   2216   talk_base::replace_substrs(gice_option.c_str(), gice_option.length(),
   2217                              xgoogle_xice.c_str(), xgoogle_xice.length(),
   2218                              &offer_str);
   2219   JsepSessionDescription *ice_only_offer =
   2220       new JsepSessionDescription(JsepSessionDescription::kOffer);
   2221   EXPECT_TRUE((ice_only_offer)->Initialize(offer_str, NULL));
   2222   SetLocalDescriptionWithoutError(ice_only_offer);
   2223   std::string original_offer_sdp;
   2224   EXPECT_TRUE(offer->ToString(&original_offer_sdp));
   2225   SessionDescriptionInterface* pranswer_with_gice =
   2226       CreateSessionDescription(JsepSessionDescription::kPrAnswer,
   2227                                original_offer_sdp, NULL);
   2228   SetRemoteDescriptionExpectError(kPushDownPranswerTDFailed,
   2229                                   pranswer_with_gice);
   2230   SessionDescriptionInterface* answer_with_gice =
   2231       CreateSessionDescription(JsepSessionDescription::kAnswer,
   2232                                original_offer_sdp, NULL);
   2233   SetRemoteDescriptionExpectError(kPushDownAnswerTDFailed,
   2234                                   answer_with_gice);
   2235 }
   2236 
   2237 // Verifing local offer and remote answer have matching m-lines as per RFC 3264.
   2238 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
   2239   Init(NULL);
   2240   mediastream_signaling_.SendAudioVideoStream1();
   2241   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2242   SetLocalDescriptionWithoutError(offer);
   2243   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   2244       CreateRemoteAnswer(session_->local_description()));
   2245 
   2246   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   2247   answer_copy->RemoveContentByName("video");
   2248   JsepSessionDescription* modified_answer =
   2249       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   2250 
   2251   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
   2252                                           answer->session_id(),
   2253                                           answer->session_version()));
   2254   SetRemoteDescriptionExpectError(kMlineMismatch, modified_answer);
   2255 
   2256   // Modifying content names.
   2257   std::string sdp;
   2258   EXPECT_TRUE(answer->ToString(&sdp));
   2259   const std::string kAudioMid = "a=mid:audio";
   2260   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
   2261 
   2262   // Replacing |audio| with |audio_content_name|.
   2263   talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
   2264                              kAudioMidReplaceStr.c_str(),
   2265                              kAudioMidReplaceStr.length(),
   2266                              &sdp);
   2267 
   2268   SessionDescriptionInterface* modified_answer1 =
   2269       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   2270   SetRemoteDescriptionExpectError(kMlineMismatch, modified_answer1);
   2271 
   2272   SetRemoteDescriptionWithoutError(answer.release());
   2273 }
   2274 
   2275 // Verifying remote offer and local answer have matching m-lines as per
   2276 // RFC 3264.
   2277 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
   2278   Init(NULL);
   2279   mediastream_signaling_.SendAudioVideoStream1();
   2280   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2281   SetRemoteDescriptionWithoutError(offer);
   2282   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2283 
   2284   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   2285   answer_copy->RemoveContentByName("video");
   2286   JsepSessionDescription* modified_answer =
   2287       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   2288 
   2289   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
   2290                                           answer->session_id(),
   2291                                           answer->session_version()));
   2292   SetLocalDescriptionExpectError(kMlineMismatch, modified_answer);
   2293   SetLocalDescriptionWithoutError(answer);
   2294 }
   2295 
   2296 // This test verifies that WebRtcSession does not start candidate allocation
   2297 // before SetLocalDescription is called.
   2298 TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
   2299   Init(NULL);
   2300   mediastream_signaling_.SendAudioVideoStream1();
   2301   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2302   cricket::Candidate candidate;
   2303   candidate.set_component(1);
   2304   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
   2305                                  candidate);
   2306   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   2307   cricket::Candidate candidate1;
   2308   candidate1.set_component(1);
   2309   JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
   2310                                   candidate1);
   2311   EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
   2312   SetRemoteDescriptionWithoutError(offer);
   2313   ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
   2314   ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
   2315 
   2316   // Pump for 1 second and verify that no candidates are generated.
   2317   talk_base::Thread::Current()->ProcessMessages(1000);
   2318   EXPECT_TRUE(observer_.mline_0_candidates_.empty());
   2319   EXPECT_TRUE(observer_.mline_1_candidates_.empty());
   2320 
   2321   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2322   SetLocalDescriptionWithoutError(answer);
   2323   EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
   2324   EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
   2325   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   2326 }
   2327 
   2328 // This test verifies that crypto parameter is updated in local session
   2329 // description as per security policy set in MediaSessionDescriptionFactory.
   2330 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
   2331   Init(NULL);
   2332   mediastream_signaling_.SendAudioVideoStream1();
   2333   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   2334       CreateOffer(NULL));
   2335 
   2336   // Making sure SetLocalDescription correctly sets crypto value in
   2337   // SessionDescription object after de-serialization of sdp string. The value
   2338   // will be set as per MediaSessionDescriptionFactory.
   2339   std::string offer_str;
   2340   offer->ToString(&offer_str);
   2341   SessionDescriptionInterface* jsep_offer_str =
   2342       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
   2343   SetLocalDescriptionWithoutError(jsep_offer_str);
   2344   EXPECT_TRUE(session_->voice_channel()->secure_required());
   2345   EXPECT_TRUE(session_->video_channel()->secure_required());
   2346 }
   2347 
   2348 // This test verifies the crypto parameter when security is disabled.
   2349 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
   2350   Init(NULL);
   2351   mediastream_signaling_.SendAudioVideoStream1();
   2352   session_->set_secure_policy(cricket::SEC_DISABLED);
   2353   talk_base::scoped_ptr<SessionDescriptionInterface> offer(
   2354       CreateOffer(NULL));
   2355 
   2356   // Making sure SetLocalDescription correctly sets crypto value in
   2357   // SessionDescription object after de-serialization of sdp string. The value
   2358   // will be set as per MediaSessionDescriptionFactory.
   2359   std::string offer_str;
   2360   offer->ToString(&offer_str);
   2361   SessionDescriptionInterface *jsep_offer_str =
   2362       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
   2363   SetLocalDescriptionWithoutError(jsep_offer_str);
   2364   EXPECT_FALSE(session_->voice_channel()->secure_required());
   2365   EXPECT_FALSE(session_->video_channel()->secure_required());
   2366 }
   2367 
   2368 // This test verifies that an answer contains new ufrag and password if an offer
   2369 // with new ufrag and password is received.
   2370 TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
   2371   Init(NULL);
   2372   cricket::MediaSessionOptions options;
   2373   options.has_audio = true;
   2374   options.has_video = true;
   2375   talk_base::scoped_ptr<JsepSessionDescription> offer(
   2376       CreateRemoteOffer(options));
   2377   SetRemoteDescriptionWithoutError(offer.release());
   2378 
   2379   mediastream_signaling_.SendAudioVideoStream1();
   2380   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   2381       CreateAnswer(NULL));
   2382   SetLocalDescriptionWithoutError(answer.release());
   2383 
   2384   // Receive an offer with new ufrag and password.
   2385   options.transport_options.ice_restart = true;
   2386   talk_base::scoped_ptr<JsepSessionDescription> updated_offer1(
   2387       CreateRemoteOffer(options, session_->remote_description()));
   2388   SetRemoteDescriptionWithoutError(updated_offer1.release());
   2389 
   2390   talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer1(
   2391       CreateAnswer(NULL));
   2392 
   2393   CompareIceUfragAndPassword(updated_answer1->description(),
   2394                              session_->local_description()->description(),
   2395                              false);
   2396 
   2397   SetLocalDescriptionWithoutError(updated_answer1.release());
   2398 }
   2399 
   2400 // This test verifies that an answer contains old ufrag and password if an offer
   2401 // with old ufrag and password is received.
   2402 TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
   2403   Init(NULL);
   2404   cricket::MediaSessionOptions options;
   2405   options.has_audio = true;
   2406   options.has_video = true;
   2407   talk_base::scoped_ptr<JsepSessionDescription> offer(
   2408       CreateRemoteOffer(options));
   2409   SetRemoteDescriptionWithoutError(offer.release());
   2410 
   2411   mediastream_signaling_.SendAudioVideoStream1();
   2412   talk_base::scoped_ptr<SessionDescriptionInterface> answer(
   2413       CreateAnswer(NULL));
   2414   SetLocalDescriptionWithoutError(answer.release());
   2415 
   2416   // Receive an offer without changed ufrag or password.
   2417   options.transport_options.ice_restart = false;
   2418   talk_base::scoped_ptr<JsepSessionDescription> updated_offer2(
   2419       CreateRemoteOffer(options, session_->remote_description()));
   2420   SetRemoteDescriptionWithoutError(updated_offer2.release());
   2421 
   2422   talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer2(
   2423       CreateAnswer(NULL));
   2424 
   2425   CompareIceUfragAndPassword(updated_answer2->description(),
   2426                              session_->local_description()->description(),
   2427                              true);
   2428 
   2429   SetLocalDescriptionWithoutError(updated_answer2.release());
   2430 }
   2431 
   2432 TEST_F(WebRtcSessionTest, TestSessionContentError) {
   2433   Init(NULL);
   2434   mediastream_signaling_.SendAudioVideoStream1();
   2435   SessionDescriptionInterface* offer = CreateOffer(NULL);
   2436   const std::string session_id_orig = offer->session_id();
   2437   const std::string session_version_orig = offer->session_version();
   2438   SetLocalDescriptionWithoutError(offer);
   2439 
   2440   video_channel_ = media_engine_->GetVideoChannel(0);
   2441   video_channel_->set_fail_set_send_codecs(true);
   2442 
   2443   mediastream_signaling_.SendAudioVideoStream2();
   2444   SessionDescriptionInterface* answer =
   2445       CreateRemoteAnswer(session_->local_description());
   2446   SetRemoteDescriptionExpectError("ERROR_CONTENT", answer);
   2447 }
   2448 
   2449 // Runs the loopback call test with BUNDLE and STUN disabled.
   2450 TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
   2451   // Lets try with only UDP ports.
   2452   allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
   2453                        cricket::PORTALLOCATOR_DISABLE_TCP |
   2454                        cricket::PORTALLOCATOR_DISABLE_STUN |
   2455                        cricket::PORTALLOCATOR_DISABLE_RELAY);
   2456   TestLoopbackCall();
   2457 }
   2458 
   2459 // Regression-test for a crash which should have been an error.
   2460 TEST_F(WebRtcSessionTest, TestNoStateTransitionPendingError) {
   2461   Init(NULL);
   2462   cricket::MediaSessionOptions options;
   2463   options.has_audio = true;
   2464   options.has_video = true;
   2465 
   2466   session_->SetError(cricket::BaseSession::ERROR_CONTENT);
   2467   SessionDescriptionInterface* offer = CreateRemoteOffer(options);
   2468   SessionDescriptionInterface* answer =
   2469       CreateRemoteAnswer(offer, options);
   2470   SetRemoteDescriptionExpectError(kSessionError, offer);
   2471   SetLocalDescriptionExpectError(kSessionError, answer);
   2472   // Not crashing is our success.
   2473 }
   2474 
   2475 TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
   2476   constraints_.reset(new FakeConstraints());
   2477   constraints_->AddOptional(
   2478       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
   2479   Init(NULL);
   2480 
   2481   SetLocalDescriptionWithDataChannel();
   2482   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
   2483 }
   2484 
   2485 TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
   2486   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2487 
   2488   constraints_.reset(new FakeConstraints());
   2489   constraints_->AddOptional(
   2490       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
   2491   constraints_->AddOptional(
   2492     webrtc::MediaConstraintsInterface::kEnableSctpDataChannels, true);
   2493   constraints_->AddOptional(
   2494       webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, true);
   2495   Init(NULL);
   2496 
   2497   SetLocalDescriptionWithDataChannel();
   2498   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
   2499 }
   2500 
   2501 TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
   2502   constraints_.reset(new FakeConstraints());
   2503   constraints_->AddOptional(
   2504       webrtc::MediaConstraintsInterface::kEnableSctpDataChannels, true);
   2505   Init(NULL);
   2506 
   2507   SetLocalDescriptionWithDataChannel();
   2508   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
   2509 }
   2510 
   2511 TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
   2512   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2513 
   2514   constraints_.reset(new FakeConstraints());
   2515   constraints_->AddOptional(
   2516       webrtc::MediaConstraintsInterface::kEnableSctpDataChannels, true);
   2517   constraints_->AddOptional(
   2518       webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, true);
   2519   Init(NULL);
   2520 
   2521   SetLocalDescriptionWithDataChannel();
   2522   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
   2523 }
   2524 
   2525 // Verifies that CreateOffer succeeds when CreateOffer is called before async
   2526 // identity generation is finished.
   2527 TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
   2528   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2529   InitWithAsyncDtls(false);
   2530 
   2531   EXPECT_TRUE(session_->waiting_for_identity());
   2532   talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
   2533   EXPECT_TRUE(offer != NULL);
   2534 }
   2535 
   2536 // Verifies that CreateAnswer succeeds when CreateOffer is called before async
   2537 // identity generation is finished.
   2538 TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
   2539   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2540   InitWithAsyncDtls(false);
   2541 
   2542   cricket::MediaSessionOptions options;
   2543   scoped_ptr<JsepSessionDescription> offer(
   2544         CreateRemoteOffer(options, cricket::SEC_REQUIRED));
   2545   ASSERT_TRUE(offer.get() != NULL);
   2546   SetRemoteDescriptionWithoutError(offer.release());
   2547 
   2548   talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   2549   EXPECT_TRUE(answer != NULL);
   2550 }
   2551 
   2552 // Verifies that CreateOffer succeeds when CreateOffer is called after async
   2553 // identity generation is finished.
   2554 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
   2555   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2556   InitWithAsyncDtls(false);
   2557 
   2558   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
   2559   talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
   2560   EXPECT_TRUE(offer != NULL);
   2561 }
   2562 
   2563 // Verifies that CreateOffer fails when CreateOffer is called after async
   2564 // identity generation fails.
   2565 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
   2566   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2567   InitWithAsyncDtls(true);
   2568 
   2569   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
   2570   talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
   2571   EXPECT_TRUE(offer == NULL);
   2572 }
   2573 
   2574 // Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
   2575 // before async identity generation is finished.
   2576 TEST_F(WebRtcSessionTest,
   2577        TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
   2578   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2579   VerifyMultipleAsyncCreateDescription(
   2580       true, CreateSessionDescriptionRequest::kOffer);
   2581 }
   2582 
   2583 // Verifies that CreateOffer fails when Multiple CreateOffer calls are made
   2584 // before async identity generation fails.
   2585 TEST_F(WebRtcSessionTest,
   2586        TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
   2587   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2588   VerifyMultipleAsyncCreateDescription(
   2589       false, CreateSessionDescriptionRequest::kOffer);
   2590 }
   2591 
   2592 // Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
   2593 // before async identity generation is finished.
   2594 TEST_F(WebRtcSessionTest,
   2595        TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
   2596   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2597   VerifyMultipleAsyncCreateDescription(
   2598       true, CreateSessionDescriptionRequest::kAnswer);
   2599 }
   2600 
   2601 // Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
   2602 // before async identity generation fails.
   2603 TEST_F(WebRtcSessionTest,
   2604        TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
   2605   MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   2606   VerifyMultipleAsyncCreateDescription(
   2607       false, CreateSessionDescriptionRequest::kAnswer);
   2608 }
   2609 // TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled.  That test
   2610 // currently fails because upon disconnection and reconnection OnIceComplete is
   2611 // called more than once without returning to IceGatheringGathering.
   2612