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