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 <utility>
     29 #include <vector>
     30 
     31 #include "talk/app/webrtc/audiotrack.h"
     32 #include "talk/app/webrtc/fakemediacontroller.h"
     33 #include "talk/app/webrtc/fakemetricsobserver.h"
     34 #include "talk/app/webrtc/jsepicecandidate.h"
     35 #include "talk/app/webrtc/jsepsessiondescription.h"
     36 #include "talk/app/webrtc/peerconnection.h"
     37 #include "talk/app/webrtc/sctputils.h"
     38 #include "talk/app/webrtc/streamcollection.h"
     39 #include "talk/app/webrtc/streamcollection.h"
     40 #include "talk/app/webrtc/test/fakeconstraints.h"
     41 #include "talk/app/webrtc/test/fakedtlsidentitystore.h"
     42 #include "talk/app/webrtc/videotrack.h"
     43 #include "talk/app/webrtc/webrtcsession.h"
     44 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
     45 #include "talk/media/base/fakemediaengine.h"
     46 #include "talk/media/base/fakevideorenderer.h"
     47 #include "talk/media/base/mediachannel.h"
     48 #include "talk/media/webrtc/fakewebrtccall.h"
     49 #include "webrtc/p2p/base/stunserver.h"
     50 #include "webrtc/p2p/base/teststunserver.h"
     51 #include "webrtc/p2p/base/testturnserver.h"
     52 #include "webrtc/p2p/base/transportchannel.h"
     53 #include "webrtc/p2p/client/basicportallocator.h"
     54 #include "talk/session/media/channelmanager.h"
     55 #include "talk/session/media/mediasession.h"
     56 #include "webrtc/base/fakenetwork.h"
     57 #include "webrtc/base/firewallsocketserver.h"
     58 #include "webrtc/base/gunit.h"
     59 #include "webrtc/base/logging.h"
     60 #include "webrtc/base/network.h"
     61 #include "webrtc/base/physicalsocketserver.h"
     62 #include "webrtc/base/ssladapter.h"
     63 #include "webrtc/base/sslidentity.h"
     64 #include "webrtc/base/sslstreamadapter.h"
     65 #include "webrtc/base/stringutils.h"
     66 #include "webrtc/base/thread.h"
     67 #include "webrtc/base/virtualsocketserver.h"
     68 
     69 #define MAYBE_SKIP_TEST(feature)                    \
     70   if (!(feature())) {                               \
     71     LOG(LS_INFO) << "Feature disabled... skipping"; \
     72     return;                                         \
     73   }
     74 
     75 using cricket::FakeVoiceMediaChannel;
     76 using cricket::TransportInfo;
     77 using rtc::SocketAddress;
     78 using rtc::scoped_ptr;
     79 using rtc::Thread;
     80 using webrtc::CreateSessionDescription;
     81 using webrtc::CreateSessionDescriptionObserver;
     82 using webrtc::CreateSessionDescriptionRequest;
     83 using webrtc::DataChannel;
     84 using webrtc::DtlsIdentityStoreInterface;
     85 using webrtc::FakeConstraints;
     86 using webrtc::FakeMetricsObserver;
     87 using webrtc::IceCandidateCollection;
     88 using webrtc::InternalDataChannelInit;
     89 using webrtc::JsepIceCandidate;
     90 using webrtc::JsepSessionDescription;
     91 using webrtc::PeerConnectionFactoryInterface;
     92 using webrtc::PeerConnectionInterface;
     93 using webrtc::SessionDescriptionInterface;
     94 using webrtc::SessionStats;
     95 using webrtc::StreamCollection;
     96 using webrtc::WebRtcSession;
     97 using webrtc::kBundleWithoutRtcpMux;
     98 using webrtc::kCreateChannelFailed;
     99 using webrtc::kInvalidSdp;
    100 using webrtc::kMlineMismatch;
    101 using webrtc::kPushDownTDFailed;
    102 using webrtc::kSdpWithoutIceUfragPwd;
    103 using webrtc::kSdpWithoutDtlsFingerprint;
    104 using webrtc::kSdpWithoutSdesCrypto;
    105 using webrtc::kSessionError;
    106 using webrtc::kSessionErrorDesc;
    107 using webrtc::kMaxUnsignalledRecvStreams;
    108 
    109 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
    110 
    111 static const int kClientAddrPort = 0;
    112 static const char kClientAddrHost1[] = "11.11.11.11";
    113 static const char kClientIPv6AddrHost1[] =
    114     "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff";
    115 static const char kClientAddrHost2[] = "22.22.22.22";
    116 static const char kStunAddrHost[] = "99.99.99.1";
    117 static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
    118 static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
    119 static const char kTurnUsername[] = "test";
    120 static const char kTurnPassword[] = "test";
    121 
    122 static const char kSessionVersion[] = "1";
    123 
    124 // Media index of candidates belonging to the first media content.
    125 static const int kMediaContentIndex0 = 0;
    126 static const char kMediaContentName0[] = "audio";
    127 
    128 // Media index of candidates belonging to the second media content.
    129 static const int kMediaContentIndex1 = 1;
    130 static const char kMediaContentName1[] = "video";
    131 
    132 static const int kIceCandidatesTimeout = 10000;
    133 
    134 static const char kFakeDtlsFingerprint[] =
    135     "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
    136     "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
    137 
    138 static const char kTooLongIceUfragPwd[] =
    139     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
    140     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
    141     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
    142     "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
    143 
    144 static const char kSdpWithRtx[] =
    145     "v=0\r\n"
    146     "o=- 4104004319237231850 2 IN IP4 127.0.0.1\r\n"
    147     "s=-\r\n"
    148     "t=0 0\r\n"
    149     "a=msid-semantic: WMS stream1\r\n"
    150     "m=video 9 RTP/SAVPF 0 96\r\n"
    151     "c=IN IP4 0.0.0.0\r\n"
    152     "a=rtcp:9 IN IP4 0.0.0.0\r\n"
    153     "a=ice-ufrag:CerjGp19G7wpXwl7\r\n"
    154     "a=ice-pwd:cMvOlFvQ6ochez1ZOoC2uBEC\r\n"
    155     "a=mid:video\r\n"
    156     "a=sendrecv\r\n"
    157     "a=rtcp-mux\r\n"
    158     "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
    159     "inline:5/4N5CDvMiyDArHtBByUM71VIkguH17ZNoX60GrA\r\n"
    160     "a=rtpmap:0 fake_video_codec/90000\r\n"
    161     "a=rtpmap:96 rtx/90000\r\n"
    162     "a=fmtp:96 apt=0\r\n";
    163 
    164 static const char kStream1[] = "stream1";
    165 static const char kVideoTrack1[] = "video1";
    166 static const char kAudioTrack1[] = "audio1";
    167 
    168 static const char kStream2[] = "stream2";
    169 static const char kVideoTrack2[] = "video2";
    170 static const char kAudioTrack2[] = "audio2";
    171 
    172 enum RTCCertificateGenerationMethod { ALREADY_GENERATED, DTLS_IDENTITY_STORE };
    173 
    174 class MockIceObserver : public webrtc::IceObserver {
    175  public:
    176   MockIceObserver()
    177       : oncandidatesready_(false),
    178         ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
    179         ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
    180   }
    181 
    182   virtual void OnIceConnectionChange(
    183       PeerConnectionInterface::IceConnectionState new_state) {
    184     ice_connection_state_ = new_state;
    185   }
    186   virtual void OnIceGatheringChange(
    187       PeerConnectionInterface::IceGatheringState new_state) {
    188     // We can never transition back to "new".
    189     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
    190     ice_gathering_state_ = new_state;
    191 
    192     // oncandidatesready_ really means "ICE gathering is complete".
    193     // This if statement ensures that this value remains correct when we
    194     // transition from kIceGatheringComplete to kIceGatheringGathering.
    195     if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
    196       oncandidatesready_ = false;
    197     }
    198   }
    199 
    200   // Found a new candidate.
    201   virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
    202     switch (candidate->sdp_mline_index()) {
    203       case kMediaContentIndex0:
    204         mline_0_candidates_.push_back(candidate->candidate());
    205         break;
    206       case kMediaContentIndex1:
    207         mline_1_candidates_.push_back(candidate->candidate());
    208         break;
    209       default:
    210         ASSERT(false);
    211     }
    212 
    213     // The ICE gathering state should always be Gathering when a candidate is
    214     // received (or possibly Completed in the case of the final candidate).
    215     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
    216   }
    217 
    218   // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
    219   virtual void OnIceComplete() {
    220     EXPECT_FALSE(oncandidatesready_);
    221     oncandidatesready_ = true;
    222 
    223     // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
    224     // be called approximately simultaneously.  For ease of testing, this
    225     // check additionally requires that they be called in the above order.
    226     EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
    227               ice_gathering_state_);
    228   }
    229 
    230   bool oncandidatesready_;
    231   std::vector<cricket::Candidate> mline_0_candidates_;
    232   std::vector<cricket::Candidate> mline_1_candidates_;
    233   PeerConnectionInterface::IceConnectionState ice_connection_state_;
    234   PeerConnectionInterface::IceGatheringState ice_gathering_state_;
    235 };
    236 
    237 class WebRtcSessionForTest : public webrtc::WebRtcSession {
    238  public:
    239   WebRtcSessionForTest(webrtc::MediaControllerInterface* media_controller,
    240                        rtc::Thread* signaling_thread,
    241                        rtc::Thread* worker_thread,
    242                        cricket::PortAllocator* port_allocator,
    243                        webrtc::IceObserver* ice_observer)
    244       : WebRtcSession(media_controller,
    245                       signaling_thread,
    246                       worker_thread,
    247                       port_allocator) {
    248     RegisterIceObserver(ice_observer);
    249   }
    250   virtual ~WebRtcSessionForTest() {}
    251 
    252   // Note that these methods are only safe to use if the signaling thread
    253   // is the same as the worker thread
    254   cricket::TransportChannel* voice_rtp_transport_channel() {
    255     return rtp_transport_channel(voice_channel());
    256   }
    257 
    258   cricket::TransportChannel* voice_rtcp_transport_channel() {
    259     return rtcp_transport_channel(voice_channel());
    260   }
    261 
    262   cricket::TransportChannel* video_rtp_transport_channel() {
    263     return rtp_transport_channel(video_channel());
    264   }
    265 
    266   cricket::TransportChannel* video_rtcp_transport_channel() {
    267     return rtcp_transport_channel(video_channel());
    268   }
    269 
    270   cricket::TransportChannel* data_rtp_transport_channel() {
    271     return rtp_transport_channel(data_channel());
    272   }
    273 
    274   cricket::TransportChannel* data_rtcp_transport_channel() {
    275     return rtcp_transport_channel(data_channel());
    276   }
    277 
    278   using webrtc::WebRtcSession::SetAudioPlayout;
    279   using webrtc::WebRtcSession::SetAudioSend;
    280   using webrtc::WebRtcSession::SetCaptureDevice;
    281   using webrtc::WebRtcSession::SetVideoPlayout;
    282   using webrtc::WebRtcSession::SetVideoSend;
    283 
    284  private:
    285   cricket::TransportChannel* rtp_transport_channel(cricket::BaseChannel* ch) {
    286     if (!ch) {
    287       return nullptr;
    288     }
    289     return ch->transport_channel();
    290   }
    291 
    292   cricket::TransportChannel* rtcp_transport_channel(cricket::BaseChannel* ch) {
    293     if (!ch) {
    294       return nullptr;
    295     }
    296     return ch->rtcp_transport_channel();
    297   }
    298 };
    299 
    300 class WebRtcSessionCreateSDPObserverForTest
    301     : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
    302  public:
    303   enum State {
    304     kInit,
    305     kFailed,
    306     kSucceeded,
    307   };
    308   WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
    309 
    310   // CreateSessionDescriptionObserver implementation.
    311   virtual void OnSuccess(SessionDescriptionInterface* desc) {
    312     description_.reset(desc);
    313     state_ = kSucceeded;
    314   }
    315   virtual void OnFailure(const std::string& error) {
    316     state_ = kFailed;
    317   }
    318 
    319   SessionDescriptionInterface* description() { return description_.get(); }
    320 
    321   SessionDescriptionInterface* ReleaseDescription() {
    322     return description_.release();
    323   }
    324 
    325   State state() const { return state_; }
    326 
    327  protected:
    328   ~WebRtcSessionCreateSDPObserverForTest() {}
    329 
    330  private:
    331   rtc::scoped_ptr<SessionDescriptionInterface> description_;
    332   State state_;
    333 };
    334 
    335 class FakeAudioRenderer : public cricket::AudioRenderer {
    336  public:
    337   FakeAudioRenderer() : sink_(NULL) {}
    338   virtual ~FakeAudioRenderer() {
    339     if (sink_)
    340       sink_->OnClose();
    341   }
    342 
    343   void SetSink(Sink* sink) override { sink_ = sink; }
    344 
    345   cricket::AudioRenderer::Sink* sink() const { return sink_; }
    346  private:
    347   cricket::AudioRenderer::Sink* sink_;
    348 };
    349 
    350 class WebRtcSessionTest
    351     : public testing::TestWithParam<RTCCertificateGenerationMethod>,
    352       public sigslot::has_slots<> {
    353  protected:
    354   // TODO Investigate why ChannelManager crashes, if it's created
    355   // after stun_server.
    356   WebRtcSessionTest()
    357       : media_engine_(new cricket::FakeMediaEngine()),
    358         data_engine_(new cricket::FakeDataEngine()),
    359         channel_manager_(
    360             new cricket::ChannelManager(media_engine_,
    361                                         data_engine_,
    362                                         new cricket::CaptureManager(),
    363                                         rtc::Thread::Current())),
    364         fake_call_(webrtc::Call::Config()),
    365         media_controller_(
    366             webrtc::MediaControllerInterface::Create(rtc::Thread::Current(),
    367                                                      channel_manager_.get())),
    368         tdesc_factory_(new cricket::TransportDescriptionFactory()),
    369         desc_factory_(
    370             new cricket::MediaSessionDescriptionFactory(channel_manager_.get(),
    371                                                         tdesc_factory_.get())),
    372         pss_(new rtc::PhysicalSocketServer),
    373         vss_(new rtc::VirtualSocketServer(pss_.get())),
    374         fss_(new rtc::FirewallSocketServer(vss_.get())),
    375         ss_scope_(fss_.get()),
    376         stun_socket_addr_(
    377             rtc::SocketAddress(kStunAddrHost, cricket::STUN_SERVER_PORT)),
    378         stun_server_(cricket::TestStunServer::Create(Thread::Current(),
    379                                                      stun_socket_addr_)),
    380         turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
    381         metrics_observer_(new rtc::RefCountedObject<FakeMetricsObserver>()) {
    382     cricket::ServerAddresses stun_servers;
    383     stun_servers.insert(stun_socket_addr_);
    384     allocator_.reset(new cricket::BasicPortAllocator(
    385         &network_manager_,
    386         stun_servers,
    387         SocketAddress(), SocketAddress(), SocketAddress()));
    388     allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
    389                           cricket::PORTALLOCATOR_DISABLE_RELAY);
    390     EXPECT_TRUE(channel_manager_->Init());
    391     desc_factory_->set_add_legacy_streams(false);
    392     allocator_->set_step_delay(cricket::kMinimumStepDelay);
    393   }
    394 
    395   void AddInterface(const SocketAddress& addr) {
    396     network_manager_.AddInterface(addr);
    397   }
    398 
    399   // If |dtls_identity_store| != null or |rtc_configuration| contains
    400   // |certificates| then DTLS will be enabled unless explicitly disabled by
    401   // |rtc_configuration| options. When DTLS is enabled a certificate will be
    402   // used if provided, otherwise one will be generated using the
    403   // |dtls_identity_store|.
    404   void Init(
    405       rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
    406       const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
    407     ASSERT_TRUE(session_.get() == NULL);
    408     session_.reset(new WebRtcSessionForTest(
    409         media_controller_.get(), rtc::Thread::Current(), rtc::Thread::Current(),
    410         allocator_.get(), &observer_));
    411     session_->SignalDataChannelOpenMessage.connect(
    412         this, &WebRtcSessionTest::OnDataChannelOpenMessage);
    413 
    414     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
    415         observer_.ice_connection_state_);
    416     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
    417         observer_.ice_gathering_state_);
    418 
    419     EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
    420                                      std::move(dtls_identity_store),
    421                                      rtc_configuration));
    422     session_->set_metrics_observer(metrics_observer_);
    423   }
    424 
    425   void OnDataChannelOpenMessage(const std::string& label,
    426                                 const InternalDataChannelInit& config) {
    427     last_data_channel_label_ = label;
    428     last_data_channel_config_ = config;
    429   }
    430 
    431   void Init() {
    432     PeerConnectionInterface::RTCConfiguration configuration;
    433     Init(nullptr, configuration);
    434   }
    435 
    436   void InitWithIceTransport(
    437       PeerConnectionInterface::IceTransportsType ice_transport_type) {
    438     PeerConnectionInterface::RTCConfiguration configuration;
    439     configuration.type = ice_transport_type;
    440     Init(nullptr, configuration);
    441   }
    442 
    443   void InitWithBundlePolicy(
    444       PeerConnectionInterface::BundlePolicy bundle_policy) {
    445     PeerConnectionInterface::RTCConfiguration configuration;
    446     configuration.bundle_policy = bundle_policy;
    447     Init(nullptr, configuration);
    448   }
    449 
    450   void InitWithRtcpMuxPolicy(
    451       PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
    452     PeerConnectionInterface::RTCConfiguration configuration;
    453     configuration.rtcp_mux_policy = rtcp_mux_policy;
    454     Init(nullptr, configuration);
    455   }
    456 
    457   // Successfully init with DTLS; with a certificate generated and supplied or
    458   // with a store that generates it for us.
    459   void InitWithDtls(RTCCertificateGenerationMethod cert_gen_method) {
    460     rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store;
    461     PeerConnectionInterface::RTCConfiguration configuration;
    462     if (cert_gen_method == ALREADY_GENERATED) {
    463       configuration.certificates.push_back(
    464           FakeDtlsIdentityStore::GenerateCertificate());
    465     } else if (cert_gen_method == DTLS_IDENTITY_STORE) {
    466       dtls_identity_store.reset(new FakeDtlsIdentityStore());
    467       dtls_identity_store->set_should_fail(false);
    468     } else {
    469       RTC_CHECK(false);
    470     }
    471     Init(std::move(dtls_identity_store), configuration);
    472   }
    473 
    474   // Init with DTLS with a store that will fail to generate a certificate.
    475   void InitWithDtlsIdentityGenFail() {
    476     rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
    477         new FakeDtlsIdentityStore());
    478     dtls_identity_store->set_should_fail(true);
    479     PeerConnectionInterface::RTCConfiguration configuration;
    480     Init(std::move(dtls_identity_store), configuration);
    481   }
    482 
    483   void InitWithDtmfCodec() {
    484     // Add kTelephoneEventCodec for dtmf test.
    485     const cricket::AudioCodec kTelephoneEventCodec(
    486         106, "telephone-event", 8000, 0, 1, 0);
    487     std::vector<cricket::AudioCodec> codecs;
    488     codecs.push_back(kTelephoneEventCodec);
    489     media_engine_->SetAudioCodecs(codecs);
    490     desc_factory_->set_audio_codecs(codecs);
    491     Init();
    492   }
    493 
    494   void SendAudioVideoStream1() {
    495     send_stream_1_ = true;
    496     send_stream_2_ = false;
    497     send_audio_ = true;
    498     send_video_ = true;
    499   }
    500 
    501   void SendAudioVideoStream2() {
    502     send_stream_1_ = false;
    503     send_stream_2_ = true;
    504     send_audio_ = true;
    505     send_video_ = true;
    506   }
    507 
    508   void SendAudioVideoStream1And2() {
    509     send_stream_1_ = true;
    510     send_stream_2_ = true;
    511     send_audio_ = true;
    512     send_video_ = true;
    513   }
    514 
    515   void SendNothing() {
    516     send_stream_1_ = false;
    517     send_stream_2_ = false;
    518     send_audio_ = false;
    519     send_video_ = false;
    520   }
    521 
    522   void SendAudioOnlyStream2() {
    523     send_stream_1_ = false;
    524     send_stream_2_ = true;
    525     send_audio_ = true;
    526     send_video_ = false;
    527   }
    528 
    529   void SendVideoOnlyStream2() {
    530     send_stream_1_ = false;
    531     send_stream_2_ = true;
    532     send_audio_ = false;
    533     send_video_ = true;
    534   }
    535 
    536   void AddStreamsToOptions(cricket::MediaSessionOptions* session_options) {
    537     if (send_stream_1_ && send_audio_) {
    538       session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1,
    539                                      kStream1);
    540     }
    541     if (send_stream_1_ && send_video_) {
    542       session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1,
    543                                      kStream1);
    544     }
    545     if (send_stream_2_ && send_audio_) {
    546       session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2,
    547                                      kStream2);
    548     }
    549     if (send_stream_2_ && send_video_) {
    550       session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2,
    551                                      kStream2);
    552     }
    553     if (data_channel_ && session_->data_channel_type() == cricket::DCT_RTP) {
    554       session_options->AddSendStream(cricket::MEDIA_TYPE_DATA,
    555                                      data_channel_->label(),
    556                                      data_channel_->label());
    557     }
    558   }
    559 
    560   void GetOptionsForOffer(
    561       const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
    562       cricket::MediaSessionOptions* session_options) {
    563     ASSERT_TRUE(ConvertRtcOptionsForOffer(rtc_options, session_options));
    564 
    565     AddStreamsToOptions(session_options);
    566     if (rtc_options.offer_to_receive_audio ==
    567         RTCOfferAnswerOptions::kUndefined) {
    568       session_options->recv_audio =
    569           session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO);
    570     }
    571     if (rtc_options.offer_to_receive_video ==
    572         RTCOfferAnswerOptions::kUndefined) {
    573       session_options->recv_video =
    574           session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO);
    575     }
    576     session_options->bundle_enabled =
    577         session_options->bundle_enabled &&
    578         (session_options->has_audio() || session_options->has_video() ||
    579          session_options->has_data());
    580 
    581     if (session_->data_channel_type() == cricket::DCT_SCTP && data_channel_) {
    582       session_options->data_channel_type = cricket::DCT_SCTP;
    583     }
    584   }
    585 
    586   void GetOptionsForAnswer(const webrtc::MediaConstraintsInterface* constraints,
    587                            cricket::MediaSessionOptions* session_options) {
    588     session_options->recv_audio = false;
    589     session_options->recv_video = false;
    590     ASSERT_TRUE(ParseConstraintsForAnswer(constraints, session_options));
    591 
    592     AddStreamsToOptions(session_options);
    593     session_options->bundle_enabled =
    594         session_options->bundle_enabled &&
    595         (session_options->has_audio() || session_options->has_video() ||
    596          session_options->has_data());
    597 
    598     if (session_->data_channel_type() == cricket::DCT_SCTP) {
    599       session_options->data_channel_type = cricket::DCT_SCTP;
    600     }
    601   }
    602 
    603   // Creates a local offer and applies it. Starts ICE.
    604   // Call SendAudioVideoStreamX() before this function
    605   // to decide which streams to create.
    606   void InitiateCall() {
    607     SessionDescriptionInterface* offer = CreateOffer();
    608     SetLocalDescriptionWithoutError(offer);
    609     EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
    610         observer_.ice_gathering_state_,
    611         kIceCandidatesTimeout);
    612   }
    613 
    614   SessionDescriptionInterface* CreateOffer() {
    615     PeerConnectionInterface::RTCOfferAnswerOptions options;
    616     options.offer_to_receive_audio =
    617         RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
    618 
    619     return CreateOffer(options);
    620   }
    621 
    622   SessionDescriptionInterface* CreateOffer(
    623       const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
    624     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
    625         observer = new WebRtcSessionCreateSDPObserverForTest();
    626     cricket::MediaSessionOptions session_options;
    627     GetOptionsForOffer(options, &session_options);
    628     session_->CreateOffer(observer, options, session_options);
    629     EXPECT_TRUE_WAIT(
    630         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
    631         2000);
    632     return observer->ReleaseDescription();
    633   }
    634 
    635   SessionDescriptionInterface* CreateAnswer(
    636       const webrtc::MediaConstraintsInterface* constraints) {
    637     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
    638         = new WebRtcSessionCreateSDPObserverForTest();
    639     cricket::MediaSessionOptions session_options;
    640     GetOptionsForAnswer(constraints, &session_options);
    641     session_->CreateAnswer(observer, constraints, session_options);
    642     EXPECT_TRUE_WAIT(
    643         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
    644         2000);
    645     return observer->ReleaseDescription();
    646   }
    647 
    648   bool ChannelsExist() const {
    649     return (session_->voice_channel() != NULL &&
    650             session_->video_channel() != NULL);
    651   }
    652 
    653   void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
    654     ASSERT_TRUE(session_.get() != NULL);
    655     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
    656     ASSERT_TRUE(content != NULL);
    657     const cricket::AudioContentDescription* audio_content =
    658         static_cast<const cricket::AudioContentDescription*>(
    659             content->description);
    660     ASSERT_TRUE(audio_content != NULL);
    661     ASSERT_EQ(1U, audio_content->cryptos().size());
    662     ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
    663     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
    664               audio_content->cryptos()[0].cipher_suite);
    665     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    666               audio_content->protocol());
    667 
    668     content = cricket::GetFirstVideoContent(sdp);
    669     ASSERT_TRUE(content != NULL);
    670     const cricket::VideoContentDescription* video_content =
    671         static_cast<const cricket::VideoContentDescription*>(
    672             content->description);
    673     ASSERT_TRUE(video_content != NULL);
    674     ASSERT_EQ(1U, video_content->cryptos().size());
    675     ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
    676               video_content->cryptos()[0].cipher_suite);
    677     ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
    678     EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
    679               video_content->protocol());
    680   }
    681 
    682   void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
    683     const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
    684     ASSERT_TRUE(content != NULL);
    685     const cricket::AudioContentDescription* audio_content =
    686         static_cast<const cricket::AudioContentDescription*>(
    687             content->description);
    688     ASSERT_TRUE(audio_content != NULL);
    689     ASSERT_EQ(0U, audio_content->cryptos().size());
    690 
    691     content = cricket::GetFirstVideoContent(sdp);
    692     ASSERT_TRUE(content != NULL);
    693     const cricket::VideoContentDescription* video_content =
    694         static_cast<const cricket::VideoContentDescription*>(
    695             content->description);
    696     ASSERT_TRUE(video_content != NULL);
    697     ASSERT_EQ(0U, video_content->cryptos().size());
    698 
    699     if (dtls) {
    700       EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
    701                 audio_content->protocol());
    702       EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
    703                 video_content->protocol());
    704     } else {
    705       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
    706                 audio_content->protocol());
    707       EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
    708                 video_content->protocol());
    709     }
    710   }
    711 
    712   // Set the internal fake description factories to do DTLS-SRTP.
    713   void SetFactoryDtlsSrtp() {
    714     desc_factory_->set_secure(cricket::SEC_DISABLED);
    715     std::string identity_name = "WebRTC" +
    716         rtc::ToString(rtc::CreateRandomId());
    717     // Confirmed to work with KT_RSA and KT_ECDSA.
    718     tdesc_factory_->set_certificate(
    719         rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>(
    720             rtc::SSLIdentity::Generate(identity_name, rtc::KT_DEFAULT))));
    721     tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
    722   }
    723 
    724   void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
    725                                bool expected) {
    726     const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
    727     ASSERT_TRUE(audio != NULL);
    728     ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
    729     const TransportInfo* video = sdp->GetTransportInfoByName("video");
    730     ASSERT_TRUE(video != NULL);
    731     ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
    732   }
    733 
    734   void VerifyAnswerFromNonCryptoOffer() {
    735     // Create an SDP without Crypto.
    736     cricket::MediaSessionOptions options;
    737     options.recv_video = true;
    738     JsepSessionDescription* offer(
    739         CreateRemoteOffer(options, cricket::SEC_DISABLED));
    740     ASSERT_TRUE(offer != NULL);
    741     VerifyNoCryptoParams(offer->description(), false);
    742     SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
    743                                          offer);
    744     const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
    745     // Answer should be NULL as no crypto params in offer.
    746     ASSERT_TRUE(answer == NULL);
    747   }
    748 
    749   void VerifyAnswerFromCryptoOffer() {
    750     cricket::MediaSessionOptions options;
    751     options.recv_video = true;
    752     options.bundle_enabled = true;
    753     scoped_ptr<JsepSessionDescription> offer(
    754         CreateRemoteOffer(options, cricket::SEC_REQUIRED));
    755     ASSERT_TRUE(offer.get() != NULL);
    756     VerifyCryptoParams(offer->description());
    757     SetRemoteDescriptionWithoutError(offer.release());
    758     scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
    759     ASSERT_TRUE(answer.get() != NULL);
    760     VerifyCryptoParams(answer->description());
    761   }
    762 
    763   void SetAndVerifyNumUnsignalledRecvStreams(
    764       int value_set, int value_expected) {
    765     constraints_.reset(new FakeConstraints());
    766     constraints_->AddOptional(
    767         webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
    768         value_set);
    769     session_.reset();
    770     Init();
    771     SendAudioVideoStream1();
    772     SessionDescriptionInterface* offer = CreateOffer();
    773 
    774     SetLocalDescriptionWithoutError(offer);
    775 
    776     video_channel_ = media_engine_->GetVideoChannel(0);
    777 
    778     ASSERT_TRUE(video_channel_ != NULL);
    779     const cricket::VideoOptions& video_options = video_channel_->options();
    780     EXPECT_EQ(value_expected,
    781               video_options.unsignalled_recv_stream_limit.value_or(-1));
    782   }
    783 
    784   void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
    785                                   const cricket::SessionDescription* desc2,
    786                                   bool expect_equal) {
    787     if (desc1->contents().size() != desc2->contents().size()) {
    788       EXPECT_FALSE(expect_equal);
    789       return;
    790     }
    791 
    792     const cricket::ContentInfos& contents = desc1->contents();
    793     cricket::ContentInfos::const_iterator it = contents.begin();
    794 
    795     for (; it != contents.end(); ++it) {
    796       const cricket::TransportDescription* transport_desc1 =
    797           desc1->GetTransportDescriptionByName(it->name);
    798       const cricket::TransportDescription* transport_desc2 =
    799           desc2->GetTransportDescriptionByName(it->name);
    800       if (!transport_desc1 || !transport_desc2) {
    801         EXPECT_FALSE(expect_equal);
    802         return;
    803       }
    804       if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
    805           transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
    806         EXPECT_FALSE(expect_equal);
    807         return;
    808       }
    809     }
    810     EXPECT_TRUE(expect_equal);
    811   }
    812 
    813   void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
    814                               std::string *sdp) {
    815     const cricket::SessionDescription* desc = current_desc->description();
    816     EXPECT_TRUE(current_desc->ToString(sdp));
    817 
    818     const cricket::ContentInfos& contents = desc->contents();
    819     cricket::ContentInfos::const_iterator it = contents.begin();
    820     // Replace ufrag and pwd lines with empty strings.
    821     for (; it != contents.end(); ++it) {
    822       const cricket::TransportDescription* transport_desc =
    823           desc->GetTransportDescriptionByName(it->name);
    824       std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
    825           + "\r\n";
    826       std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
    827           + "\r\n";
    828       rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
    829                                  "", 0,
    830                                  sdp);
    831       rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
    832                                  "", 0,
    833                                  sdp);
    834     }
    835   }
    836 
    837   void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
    838                               const std::string& modified_ice_ufrag,
    839                               const std::string& modified_ice_pwd,
    840                               std::string* sdp) {
    841     const cricket::SessionDescription* desc = current_desc->description();
    842     EXPECT_TRUE(current_desc->ToString(sdp));
    843 
    844     const cricket::ContentInfos& contents = desc->contents();
    845     cricket::ContentInfos::const_iterator it = contents.begin();
    846     // Replace ufrag and pwd lines with |modified_ice_ufrag| and
    847     // |modified_ice_pwd| strings.
    848     for (; it != contents.end(); ++it) {
    849       const cricket::TransportDescription* transport_desc =
    850           desc->GetTransportDescriptionByName(it->name);
    851       std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
    852           + "\r\n";
    853       std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
    854           + "\r\n";
    855       std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
    856       std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
    857       rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
    858                                  mod_ufrag.c_str(), mod_ufrag.length(),
    859                                  sdp);
    860       rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
    861                                  mod_pwd.c_str(), mod_pwd.length(),
    862                                  sdp);
    863     }
    864   }
    865 
    866   // Creates a remote offer and and applies it as a remote description,
    867   // creates a local answer and applies is as a local description.
    868   // Call SendAudioVideoStreamX() before this function
    869   // to decide which local and remote streams to create.
    870   void CreateAndSetRemoteOfferAndLocalAnswer() {
    871     SessionDescriptionInterface* offer = CreateRemoteOffer();
    872     SetRemoteDescriptionWithoutError(offer);
    873     SessionDescriptionInterface* answer = CreateAnswer(NULL);
    874     SetLocalDescriptionWithoutError(answer);
    875   }
    876   void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
    877     EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
    878     session_->MaybeStartGathering();
    879   }
    880   void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
    881                                       WebRtcSession::State expected_state) {
    882     SetLocalDescriptionWithoutError(desc);
    883     EXPECT_EQ(expected_state, session_->state());
    884   }
    885   void SetLocalDescriptionExpectError(const std::string& action,
    886                                       const std::string& expected_error,
    887                                       SessionDescriptionInterface* desc) {
    888     std::string error;
    889     EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
    890     std::string sdp_type = "local ";
    891     sdp_type.append(action);
    892     EXPECT_NE(std::string::npos, error.find(sdp_type));
    893     EXPECT_NE(std::string::npos, error.find(expected_error));
    894   }
    895   void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
    896                                            SessionDescriptionInterface* desc) {
    897     SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
    898                                    expected_error, desc);
    899   }
    900   void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
    901                                             SessionDescriptionInterface* desc) {
    902     SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
    903                                    expected_error, desc);
    904   }
    905   void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
    906     EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
    907   }
    908   void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
    909                                        WebRtcSession::State expected_state) {
    910     SetRemoteDescriptionWithoutError(desc);
    911     EXPECT_EQ(expected_state, session_->state());
    912   }
    913   void SetRemoteDescriptionExpectError(const std::string& action,
    914                                        const std::string& expected_error,
    915                                        SessionDescriptionInterface* desc) {
    916     std::string error;
    917     EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
    918     std::string sdp_type = "remote ";
    919     sdp_type.append(action);
    920     EXPECT_NE(std::string::npos, error.find(sdp_type));
    921     EXPECT_NE(std::string::npos, error.find(expected_error));
    922   }
    923   void SetRemoteDescriptionOfferExpectError(
    924       const std::string& expected_error, SessionDescriptionInterface* desc) {
    925     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
    926                                     expected_error, desc);
    927   }
    928   void SetRemoteDescriptionPranswerExpectError(
    929       const std::string& expected_error, SessionDescriptionInterface* desc) {
    930     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
    931                                     expected_error, desc);
    932   }
    933   void SetRemoteDescriptionAnswerExpectError(
    934       const std::string& expected_error, SessionDescriptionInterface* desc) {
    935     SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
    936                                     expected_error, desc);
    937   }
    938 
    939   void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
    940       SessionDescriptionInterface** nocrypto_answer) {
    941     // Create a SDP without Crypto.
    942     cricket::MediaSessionOptions options;
    943     options.recv_video = true;
    944     options.bundle_enabled = true;
    945     *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
    946     ASSERT_TRUE(*offer != NULL);
    947     VerifyCryptoParams((*offer)->description());
    948 
    949     *nocrypto_answer = CreateRemoteAnswer(*offer, options,
    950                                           cricket::SEC_DISABLED);
    951     EXPECT_TRUE(*nocrypto_answer != NULL);
    952   }
    953 
    954   void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
    955       SessionDescriptionInterface** nodtls_answer) {
    956     cricket::MediaSessionOptions options;
    957     options.recv_video = true;
    958     options.bundle_enabled = true;
    959 
    960     rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
    961         CreateRemoteOffer(options, cricket::SEC_ENABLED));
    962 
    963     *nodtls_answer =
    964         CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
    965     EXPECT_TRUE(*nodtls_answer != NULL);
    966     VerifyFingerprintStatus((*nodtls_answer)->description(), false);
    967     VerifyCryptoParams((*nodtls_answer)->description());
    968 
    969     SetFactoryDtlsSrtp();
    970     *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
    971     ASSERT_TRUE(*offer != NULL);
    972     VerifyFingerprintStatus((*offer)->description(), true);
    973     VerifyCryptoParams((*offer)->description());
    974   }
    975 
    976   JsepSessionDescription* CreateRemoteOfferWithVersion(
    977         cricket::MediaSessionOptions options,
    978         cricket::SecurePolicy secure_policy,
    979         const std::string& session_version,
    980         const SessionDescriptionInterface* current_desc) {
    981     std::string session_id = rtc::ToString(rtc::CreateRandomId64());
    982     const cricket::SessionDescription* cricket_desc = NULL;
    983     if (current_desc) {
    984       cricket_desc = current_desc->description();
    985       session_id = current_desc->session_id();
    986     }
    987 
    988     desc_factory_->set_secure(secure_policy);
    989     JsepSessionDescription* offer(
    990         new JsepSessionDescription(JsepSessionDescription::kOffer));
    991     if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
    992                            session_id, session_version)) {
    993       delete offer;
    994       offer = NULL;
    995     }
    996     return offer;
    997   }
    998   JsepSessionDescription* CreateRemoteOffer(
    999       cricket::MediaSessionOptions options) {
   1000     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
   1001                                         kSessionVersion, NULL);
   1002   }
   1003   JsepSessionDescription* CreateRemoteOffer(
   1004       cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
   1005     return CreateRemoteOfferWithVersion(
   1006         options, sdes_policy, kSessionVersion, NULL);
   1007   }
   1008   JsepSessionDescription* CreateRemoteOffer(
   1009       cricket::MediaSessionOptions options,
   1010       const SessionDescriptionInterface* current_desc) {
   1011     return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
   1012                                         kSessionVersion, current_desc);
   1013   }
   1014 
   1015   JsepSessionDescription* CreateRemoteOfferWithSctpPort(
   1016       const char* sctp_stream_name, int new_port,
   1017       cricket::MediaSessionOptions options) {
   1018     options.data_channel_type = cricket::DCT_SCTP;
   1019     options.AddSendStream(cricket::MEDIA_TYPE_DATA, "datachannel",
   1020                           sctp_stream_name);
   1021     return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
   1022   }
   1023 
   1024   // Takes ownership of offer_basis (and deletes it).
   1025   JsepSessionDescription* ChangeSDPSctpPort(
   1026       int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
   1027     // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
   1028     // SessionDescription from the mutated string.
   1029     const char* default_port_str = "5000";
   1030     char new_port_str[16];
   1031     rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
   1032     std::string offer_str;
   1033     offer_basis->ToString(&offer_str);
   1034     rtc::replace_substrs(default_port_str, strlen(default_port_str),
   1035                                new_port_str, strlen(new_port_str),
   1036                                &offer_str);
   1037     JsepSessionDescription* offer = new JsepSessionDescription(
   1038         offer_basis->type());
   1039     delete offer_basis;
   1040     offer->Initialize(offer_str, NULL);
   1041     return offer;
   1042   }
   1043 
   1044   // Create a remote offer. Call SendAudioVideoStreamX()
   1045   // before this function to decide which streams to create.
   1046   JsepSessionDescription* CreateRemoteOffer() {
   1047     cricket::MediaSessionOptions options;
   1048     GetOptionsForAnswer(NULL, &options);
   1049     return CreateRemoteOffer(options, session_->remote_description());
   1050   }
   1051 
   1052   JsepSessionDescription* CreateRemoteAnswer(
   1053       const SessionDescriptionInterface* offer,
   1054       cricket::MediaSessionOptions options,
   1055       cricket::SecurePolicy policy) {
   1056     desc_factory_->set_secure(policy);
   1057     const std::string session_id =
   1058         rtc::ToString(rtc::CreateRandomId64());
   1059     JsepSessionDescription* answer(
   1060         new JsepSessionDescription(JsepSessionDescription::kAnswer));
   1061     if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
   1062                                                         options, NULL),
   1063                             session_id, kSessionVersion)) {
   1064       delete answer;
   1065       answer = NULL;
   1066     }
   1067     return answer;
   1068   }
   1069 
   1070   JsepSessionDescription* CreateRemoteAnswer(
   1071       const SessionDescriptionInterface* offer,
   1072       cricket::MediaSessionOptions options) {
   1073       return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
   1074   }
   1075 
   1076   // Creates an answer session description.
   1077   // Call SendAudioVideoStreamX() before this function
   1078   // to decide which streams to create.
   1079   JsepSessionDescription* CreateRemoteAnswer(
   1080       const SessionDescriptionInterface* offer) {
   1081     cricket::MediaSessionOptions options;
   1082     GetOptionsForAnswer(NULL, &options);
   1083     return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
   1084   }
   1085 
   1086   void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
   1087     AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1088     Init();
   1089     SendAudioVideoStream1();
   1090 
   1091     PeerConnectionInterface::RTCOfferAnswerOptions options;
   1092     options.use_rtp_mux = bundle;
   1093 
   1094     SessionDescriptionInterface* offer = CreateOffer(options);
   1095     // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
   1096     // and answer.
   1097     SetLocalDescriptionWithoutError(offer);
   1098 
   1099     rtc::scoped_ptr<SessionDescriptionInterface> answer(
   1100         CreateRemoteAnswer(session_->local_description()));
   1101     std::string sdp;
   1102     EXPECT_TRUE(answer->ToString(&sdp));
   1103 
   1104     size_t expected_candidate_num = 2;
   1105     if (!rtcp_mux) {
   1106       // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
   1107       // for rtp and rtcp.
   1108       expected_candidate_num = 4;
   1109       // Disable rtcp-mux from the answer
   1110       const std::string kRtcpMux = "a=rtcp-mux";
   1111       const std::string kXRtcpMux = "a=xrtcp-mux";
   1112       rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
   1113                                  kXRtcpMux.c_str(), kXRtcpMux.length(),
   1114                                  &sdp);
   1115     }
   1116 
   1117     SessionDescriptionInterface* new_answer = CreateSessionDescription(
   1118         JsepSessionDescription::kAnswer, sdp, NULL);
   1119 
   1120     // SetRemoteDescription to enable rtcp mux.
   1121     SetRemoteDescriptionWithoutError(new_answer);
   1122     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1123     EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
   1124     if (bundle) {
   1125       EXPECT_EQ(0, observer_.mline_1_candidates_.size());
   1126     } else {
   1127       EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
   1128     }
   1129   }
   1130   // Tests that we can only send DTMF when the dtmf codec is supported.
   1131   void TestCanInsertDtmf(bool can) {
   1132     if (can) {
   1133       InitWithDtmfCodec();
   1134     } else {
   1135       Init();
   1136     }
   1137     SendAudioVideoStream1();
   1138     CreateAndSetRemoteOfferAndLocalAnswer();
   1139     EXPECT_FALSE(session_->CanInsertDtmf(""));
   1140     EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
   1141   }
   1142 
   1143   // Helper class to configure loopback network and verify Best
   1144   // Connection using right IP protocol for TestLoopbackCall
   1145   // method. LoopbackNetworkManager applies firewall rules to block
   1146   // all ping traffic once ICE completed, and remove them to observe
   1147   // ICE reconnected again. This LoopbackNetworkConfiguration struct
   1148   // verifies the best connection is using the right IP protocol after
   1149   // initial ICE convergences.
   1150 
   1151   class LoopbackNetworkConfiguration {
   1152    public:
   1153     LoopbackNetworkConfiguration()
   1154         : test_ipv6_network_(false),
   1155           test_extra_ipv4_network_(false),
   1156           best_connection_after_initial_ice_converged_(1, 0) {}
   1157 
   1158     // Used to track the expected best connection count in each IP protocol.
   1159     struct ExpectedBestConnection {
   1160       ExpectedBestConnection(int ipv4_count, int ipv6_count)
   1161           : ipv4_count_(ipv4_count),
   1162             ipv6_count_(ipv6_count) {}
   1163 
   1164       int ipv4_count_;
   1165       int ipv6_count_;
   1166     };
   1167 
   1168     bool test_ipv6_network_;
   1169     bool test_extra_ipv4_network_;
   1170     ExpectedBestConnection best_connection_after_initial_ice_converged_;
   1171 
   1172     void VerifyBestConnectionAfterIceConverge(
   1173         const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer) const {
   1174       Verify(metrics_observer, best_connection_after_initial_ice_converged_);
   1175     }
   1176 
   1177    private:
   1178     void Verify(const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer,
   1179                 const ExpectedBestConnection& expected) const {
   1180       EXPECT_EQ(
   1181           metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
   1182                                            webrtc::kBestConnections_IPv4),
   1183           expected.ipv4_count_);
   1184       EXPECT_EQ(
   1185           metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
   1186                                            webrtc::kBestConnections_IPv6),
   1187           expected.ipv6_count_);
   1188       // This is used in the loopback call so there is only single host to host
   1189       // candidate pair.
   1190       EXPECT_EQ(metrics_observer->GetEnumCounter(
   1191                     webrtc::kEnumCounterIceCandidatePairTypeUdp,
   1192                     webrtc::kIceCandidatePairHostHost),
   1193                 0);
   1194       EXPECT_EQ(metrics_observer->GetEnumCounter(
   1195                     webrtc::kEnumCounterIceCandidatePairTypeUdp,
   1196                     webrtc::kIceCandidatePairHostPublicHostPublic),
   1197                 1);
   1198     }
   1199   };
   1200 
   1201   class LoopbackNetworkManager {
   1202    public:
   1203     LoopbackNetworkManager(WebRtcSessionTest* session,
   1204                            const LoopbackNetworkConfiguration& config)
   1205         : config_(config) {
   1206       session->AddInterface(
   1207           rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1208       if (config_.test_extra_ipv4_network_) {
   1209         session->AddInterface(
   1210             rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   1211       }
   1212       if (config_.test_ipv6_network_) {
   1213         session->AddInterface(
   1214             rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
   1215       }
   1216     }
   1217 
   1218     void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
   1219       fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
   1220                    rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1221       if (config_.test_extra_ipv4_network_) {
   1222         fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
   1223                      rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   1224       }
   1225       if (config_.test_ipv6_network_) {
   1226         fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
   1227                      rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
   1228       }
   1229     }
   1230 
   1231     void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
   1232 
   1233    private:
   1234     LoopbackNetworkConfiguration config_;
   1235   };
   1236 
   1237   // The method sets up a call from the session to itself, in a loopback
   1238   // arrangement.  It also uses a firewall rule to create a temporary
   1239   // disconnection, and then a permanent disconnection.
   1240   // This code is placed in a method so that it can be invoked
   1241   // by multiple tests with different allocators (e.g. with and without BUNDLE).
   1242   // While running the call, this method also checks if the session goes through
   1243   // the correct sequence of ICE states when a connection is established,
   1244   // broken, and re-established.
   1245   // The Connection state should go:
   1246   // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
   1247   //     -> Failed.
   1248   // The Gathering state should go: New -> Gathering -> Completed.
   1249 
   1250   void SetupLoopbackCall() {
   1251     Init();
   1252     SendAudioVideoStream1();
   1253     SessionDescriptionInterface* offer = CreateOffer();
   1254 
   1255     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
   1256               observer_.ice_gathering_state_);
   1257     SetLocalDescriptionWithoutError(offer);
   1258     EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
   1259               observer_.ice_connection_state_);
   1260     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
   1261                    observer_.ice_gathering_state_, kIceCandidatesTimeout);
   1262     EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1263     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
   1264                    observer_.ice_gathering_state_, kIceCandidatesTimeout);
   1265 
   1266     std::string sdp;
   1267     offer->ToString(&sdp);
   1268     SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
   1269         JsepSessionDescription::kAnswer, sdp, nullptr);
   1270     ASSERT_TRUE(desc != NULL);
   1271     SetRemoteDescriptionWithoutError(desc);
   1272 
   1273     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
   1274                    observer_.ice_connection_state_, kIceCandidatesTimeout);
   1275 
   1276     // The ice connection state is "Connected" too briefly to catch in a test.
   1277     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
   1278                    observer_.ice_connection_state_, kIceCandidatesTimeout);
   1279   }
   1280 
   1281   void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
   1282     LoopbackNetworkManager loopback_network_manager(this, config);
   1283     SetupLoopbackCall();
   1284     config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
   1285     // Adding firewall rule to block ping requests, which should cause
   1286     // transport channel failure.
   1287 
   1288     loopback_network_manager.ApplyFirewallRules(fss_.get());
   1289 
   1290     LOG(LS_INFO) << "Firewall Rules applied";
   1291     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
   1292                    observer_.ice_connection_state_,
   1293                    kIceCandidatesTimeout);
   1294 
   1295     metrics_observer_->Reset();
   1296 
   1297     // Clearing the rules, session should move back to completed state.
   1298     loopback_network_manager.ClearRules(fss_.get());
   1299 
   1300     LOG(LS_INFO) << "Firewall Rules cleared";
   1301     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
   1302                    observer_.ice_connection_state_,
   1303                    kIceCandidatesTimeout);
   1304 
   1305     // Now we block ping requests and wait until the ICE connection transitions
   1306     // to the Failed state.  This will take at least 30 seconds because it must
   1307     // wait for the Port to timeout.
   1308     int port_timeout = 30000;
   1309 
   1310     loopback_network_manager.ApplyFirewallRules(fss_.get());
   1311     LOG(LS_INFO) << "Firewall Rules applied again";
   1312     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
   1313                    observer_.ice_connection_state_,
   1314                    kIceCandidatesTimeout + port_timeout);
   1315   }
   1316 
   1317   void TestLoopbackCall() {
   1318     LoopbackNetworkConfiguration config;
   1319     TestLoopbackCall(config);
   1320   }
   1321 
   1322   void TestPacketOptions() {
   1323     media_controller_.reset(
   1324         new cricket::FakeMediaController(channel_manager_.get(), &fake_call_));
   1325     LoopbackNetworkConfiguration config;
   1326     LoopbackNetworkManager loopback_network_manager(this, config);
   1327 
   1328     SetupLoopbackCall();
   1329 
   1330     uint8_t test_packet[15] = {0};
   1331     rtc::PacketOptions options;
   1332     options.packet_id = 10;
   1333     media_engine_->GetVideoChannel(0)
   1334         ->SendRtp(test_packet, sizeof(test_packet), options);
   1335 
   1336     const int kPacketTimeout = 2000;
   1337     EXPECT_EQ_WAIT(fake_call_.last_sent_packet().packet_id, 10, kPacketTimeout);
   1338     EXPECT_GT(fake_call_.last_sent_packet().send_time_ms, -1);
   1339   }
   1340 
   1341   // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
   1342   void AddCNCodecs() {
   1343     const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
   1344     const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
   1345 
   1346     // Add kCNCodec for dtmf test.
   1347     std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
   1348     codecs.push_back(kCNCodec1);
   1349     codecs.push_back(kCNCodec2);
   1350     media_engine_->SetAudioCodecs(codecs);
   1351     desc_factory_->set_audio_codecs(codecs);
   1352   }
   1353 
   1354   bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
   1355     const cricket::ContentDescription* description = content->description;
   1356     ASSERT(description != NULL);
   1357     const cricket::AudioContentDescription* audio_content_desc =
   1358         static_cast<const cricket::AudioContentDescription*>(description);
   1359     ASSERT(audio_content_desc != NULL);
   1360     for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
   1361       if (audio_content_desc->codecs()[i].name == "CN")
   1362         return false;
   1363     }
   1364     return true;
   1365   }
   1366 
   1367   void CreateDataChannel() {
   1368     webrtc::InternalDataChannelInit dci;
   1369     dci.reliable = session_->data_channel_type() == cricket::DCT_SCTP;
   1370     data_channel_ = DataChannel::Create(
   1371         session_.get(), session_->data_channel_type(), "datachannel", dci);
   1372   }
   1373 
   1374   void SetLocalDescriptionWithDataChannel() {
   1375     CreateDataChannel();
   1376     SessionDescriptionInterface* offer = CreateOffer();
   1377     SetLocalDescriptionWithoutError(offer);
   1378   }
   1379 
   1380   void VerifyMultipleAsyncCreateDescription(
   1381       RTCCertificateGenerationMethod cert_gen_method,
   1382       CreateSessionDescriptionRequest::Type type) {
   1383     InitWithDtls(cert_gen_method);
   1384     VerifyMultipleAsyncCreateDescriptionAfterInit(true, type);
   1385   }
   1386 
   1387   void VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
   1388       CreateSessionDescriptionRequest::Type type) {
   1389     InitWithDtlsIdentityGenFail();
   1390     VerifyMultipleAsyncCreateDescriptionAfterInit(false, type);
   1391   }
   1392 
   1393   void VerifyMultipleAsyncCreateDescriptionAfterInit(
   1394       bool success, CreateSessionDescriptionRequest::Type type) {
   1395     RTC_CHECK(session_);
   1396     SetFactoryDtlsSrtp();
   1397     if (type == CreateSessionDescriptionRequest::kAnswer) {
   1398       cricket::MediaSessionOptions options;
   1399       scoped_ptr<JsepSessionDescription> offer(
   1400             CreateRemoteOffer(options, cricket::SEC_DISABLED));
   1401       ASSERT_TRUE(offer.get() != NULL);
   1402       SetRemoteDescriptionWithoutError(offer.release());
   1403     }
   1404 
   1405     PeerConnectionInterface::RTCOfferAnswerOptions options;
   1406     cricket::MediaSessionOptions session_options;
   1407     const int kNumber = 3;
   1408     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
   1409         observers[kNumber];
   1410     for (int i = 0; i < kNumber; ++i) {
   1411       observers[i] = new WebRtcSessionCreateSDPObserverForTest();
   1412       if (type == CreateSessionDescriptionRequest::kOffer) {
   1413         session_->CreateOffer(observers[i], options, session_options);
   1414       } else {
   1415         session_->CreateAnswer(observers[i], nullptr, session_options);
   1416       }
   1417     }
   1418 
   1419     WebRtcSessionCreateSDPObserverForTest::State expected_state =
   1420         success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
   1421                   WebRtcSessionCreateSDPObserverForTest::kFailed;
   1422 
   1423     for (int i = 0; i < kNumber; ++i) {
   1424       EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
   1425       if (success) {
   1426         EXPECT_TRUE(observers[i]->description() != NULL);
   1427       } else {
   1428         EXPECT_TRUE(observers[i]->description() == NULL);
   1429       }
   1430     }
   1431   }
   1432 
   1433   void ConfigureAllocatorWithTurn() {
   1434     cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
   1435     cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
   1436     turn_server.credentials = credentials;
   1437     turn_server.ports.push_back(
   1438         cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
   1439     allocator_->AddTurnServer(turn_server);
   1440     allocator_->set_step_delay(cricket::kMinimumStepDelay);
   1441     allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
   1442   }
   1443 
   1444   cricket::FakeMediaEngine* media_engine_;
   1445   cricket::FakeDataEngine* data_engine_;
   1446   rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
   1447   cricket::FakeCall fake_call_;
   1448   rtc::scoped_ptr<webrtc::MediaControllerInterface> media_controller_;
   1449   rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
   1450   rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
   1451   rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
   1452   rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
   1453   rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
   1454   rtc::SocketServerScope ss_scope_;
   1455   rtc::SocketAddress stun_socket_addr_;
   1456   rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
   1457   cricket::TestTurnServer turn_server_;
   1458   rtc::FakeNetworkManager network_manager_;
   1459   rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
   1460   PeerConnectionFactoryInterface::Options options_;
   1461   rtc::scoped_ptr<FakeConstraints> constraints_;
   1462   rtc::scoped_ptr<WebRtcSessionForTest> session_;
   1463   MockIceObserver observer_;
   1464   cricket::FakeVideoMediaChannel* video_channel_;
   1465   cricket::FakeVoiceMediaChannel* voice_channel_;
   1466   rtc::scoped_refptr<FakeMetricsObserver> metrics_observer_;
   1467   // The following flags affect options created for CreateOffer/CreateAnswer.
   1468   bool send_stream_1_ = false;
   1469   bool send_stream_2_ = false;
   1470   bool send_audio_ = false;
   1471   bool send_video_ = false;
   1472   rtc::scoped_refptr<DataChannel> data_channel_;
   1473   // Last values received from data channel creation signal.
   1474   std::string last_data_channel_label_;
   1475   InternalDataChannelInit last_data_channel_config_;
   1476 };
   1477 
   1478 TEST_P(WebRtcSessionTest, TestInitializeWithDtls) {
   1479   InitWithDtls(GetParam());
   1480   // SDES is disabled when DTLS is on.
   1481   EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
   1482 }
   1483 
   1484 TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
   1485   Init();
   1486   // SDES is required if DTLS is off.
   1487   EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
   1488 }
   1489 
   1490 TEST_F(WebRtcSessionTest, TestSessionCandidates) {
   1491   TestSessionCandidatesWithBundleRtcpMux(false, false);
   1492 }
   1493 
   1494 // Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
   1495 // with rtcp-mux and/or bundle.
   1496 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
   1497   TestSessionCandidatesWithBundleRtcpMux(false, true);
   1498 }
   1499 
   1500 TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
   1501   TestSessionCandidatesWithBundleRtcpMux(true, true);
   1502 }
   1503 
   1504 TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
   1505   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1506   AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   1507   Init();
   1508   SendAudioVideoStream1();
   1509   InitiateCall();
   1510   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1511   EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
   1512   EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
   1513 }
   1514 
   1515 TEST_F(WebRtcSessionTest, TestStunError) {
   1516   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1517   AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   1518   fss_->AddRule(false,
   1519                 rtc::FP_UDP,
   1520                 rtc::FD_ANY,
   1521                 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1522   Init();
   1523   SendAudioVideoStream1();
   1524   InitiateCall();
   1525   // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
   1526   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1527   EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
   1528   EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
   1529 }
   1530 
   1531 // Test session delivers no candidates gathered when constraint set to "none".
   1532 TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
   1533   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1534   InitWithIceTransport(PeerConnectionInterface::kNone);
   1535   SendAudioVideoStream1();
   1536   InitiateCall();
   1537   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1538   EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
   1539   EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
   1540 }
   1541 
   1542 // Test session delivers only relay candidates gathered when constaint set to
   1543 // "relay".
   1544 TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
   1545   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1546   ConfigureAllocatorWithTurn();
   1547   InitWithIceTransport(PeerConnectionInterface::kRelay);
   1548   SendAudioVideoStream1();
   1549   InitiateCall();
   1550   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1551   EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
   1552   EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
   1553   for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
   1554     EXPECT_EQ(cricket::RELAY_PORT_TYPE,
   1555               observer_.mline_0_candidates_[i].type());
   1556   }
   1557   for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
   1558     EXPECT_EQ(cricket::RELAY_PORT_TYPE,
   1559               observer_.mline_1_candidates_[i].type());
   1560   }
   1561 }
   1562 
   1563 // Test session delivers all candidates gathered when constaint set to "all".
   1564 TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
   1565   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   1566   InitWithIceTransport(PeerConnectionInterface::kAll);
   1567   SendAudioVideoStream1();
   1568   InitiateCall();
   1569   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   1570   // Host + STUN. By default allocator is disabled to gather relay candidates.
   1571   EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
   1572   EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
   1573 }
   1574 
   1575 TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
   1576   Init();
   1577   SessionDescriptionInterface* offer = NULL;
   1578   // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
   1579   std::string unknown_action;
   1580   SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
   1581   SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
   1582 }
   1583 
   1584 // Test creating offers and receive answers and make sure the
   1585 // media engine creates the expected send and receive streams.
   1586 TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
   1587   Init();
   1588   SendAudioVideoStream1();
   1589   SessionDescriptionInterface* offer = CreateOffer();
   1590   const std::string session_id_orig = offer->session_id();
   1591   const std::string session_version_orig = offer->session_version();
   1592   SetLocalDescriptionWithoutError(offer);
   1593 
   1594   SendAudioVideoStream2();
   1595   SessionDescriptionInterface* answer =
   1596       CreateRemoteAnswer(session_->local_description());
   1597   SetRemoteDescriptionWithoutError(answer);
   1598 
   1599   video_channel_ = media_engine_->GetVideoChannel(0);
   1600   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1601 
   1602   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1603   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
   1604 
   1605   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1606   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
   1607 
   1608   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1609   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
   1610   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1611   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
   1612 
   1613   // Create new offer without send streams.
   1614   SendNothing();
   1615   offer = CreateOffer();
   1616 
   1617   // Verify the session id is the same and the session version is
   1618   // increased.
   1619   EXPECT_EQ(session_id_orig, offer->session_id());
   1620   EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
   1621             rtc::FromString<uint64_t>(offer->session_version()));
   1622 
   1623   SetLocalDescriptionWithoutError(offer);
   1624   EXPECT_EQ(0u, video_channel_->send_streams().size());
   1625   EXPECT_EQ(0u, voice_channel_->send_streams().size());
   1626 
   1627   SendAudioVideoStream2();
   1628   answer = CreateRemoteAnswer(session_->local_description());
   1629   SetRemoteDescriptionWithoutError(answer);
   1630 
   1631   // Make sure the receive streams have not changed.
   1632   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1633   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
   1634   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1635   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
   1636 }
   1637 
   1638 // Test receiving offers and creating answers and make sure the
   1639 // media engine creates the expected send and receive streams.
   1640 TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
   1641   Init();
   1642   SendAudioVideoStream2();
   1643   SessionDescriptionInterface* offer = CreateOffer();
   1644   VerifyCryptoParams(offer->description());
   1645   SetRemoteDescriptionWithoutError(offer);
   1646 
   1647   SendAudioVideoStream1();
   1648   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1649   VerifyCryptoParams(answer->description());
   1650   SetLocalDescriptionWithoutError(answer);
   1651 
   1652   const std::string session_id_orig = answer->session_id();
   1653   const std::string session_version_orig = answer->session_version();
   1654 
   1655   video_channel_ = media_engine_->GetVideoChannel(0);
   1656   voice_channel_ = media_engine_->GetVoiceChannel(0);
   1657 
   1658   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   1659   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
   1660 
   1661   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   1662   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
   1663 
   1664   ASSERT_EQ(1u, video_channel_->send_streams().size());
   1665   EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
   1666   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   1667   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
   1668 
   1669   SendAudioVideoStream1And2();
   1670   offer = CreateOffer();
   1671   SetRemoteDescriptionWithoutError(offer);
   1672 
   1673   // Answer by turning off all send streams.
   1674   SendNothing();
   1675   answer = CreateAnswer(NULL);
   1676 
   1677   // Verify the session id is the same and the session version is
   1678   // increased.
   1679   EXPECT_EQ(session_id_orig, answer->session_id());
   1680   EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
   1681             rtc::FromString<uint64_t>(answer->session_version()));
   1682   SetLocalDescriptionWithoutError(answer);
   1683 
   1684   ASSERT_EQ(2u, video_channel_->recv_streams().size());
   1685   EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
   1686   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
   1687   ASSERT_EQ(2u, voice_channel_->recv_streams().size());
   1688   EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
   1689   EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
   1690 
   1691   // Make sure we have no send streams.
   1692   EXPECT_EQ(0u, video_channel_->send_streams().size());
   1693   EXPECT_EQ(0u, voice_channel_->send_streams().size());
   1694 }
   1695 
   1696 TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
   1697   Init();
   1698   media_engine_->set_fail_create_channel(true);
   1699 
   1700   SessionDescriptionInterface* offer = CreateOffer();
   1701   ASSERT_TRUE(offer != NULL);
   1702   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1703   // the offer.
   1704   SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
   1705   offer = CreateOffer();
   1706   ASSERT_TRUE(offer != NULL);
   1707   SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
   1708 }
   1709 
   1710 //
   1711 // Tests for creating/setting SDP under different SDES/DTLS polices:
   1712 //
   1713 // --DTLS off and SDES on
   1714 // TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
   1715 //     set local/remote offer/answer with crypto --> success
   1716 // TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
   1717 //     failure
   1718 // TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
   1719 //     failure
   1720 // TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
   1721 //     failure
   1722 //
   1723 // --DTLS on and SDES off
   1724 // TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
   1725 //     set local/remote offer/answer with DTLS fingerprint --> success
   1726 // TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
   1727 //     fingerprint --> failure
   1728 // TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
   1729 //     --> failure
   1730 // TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
   1731 //     --> failure
   1732 //
   1733 // --Encryption disabled: DTLS off and SDES off
   1734 // TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
   1735 //     answer without SDES or DTLS --> success
   1736 // TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
   1737 //     answer without SDES or DTLS --> success
   1738 //
   1739 
   1740 // Test that we return a failure when applying a remote/local offer that doesn't
   1741 // have cryptos enabled when DTLS is off.
   1742 TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
   1743   Init();
   1744   cricket::MediaSessionOptions options;
   1745   options.recv_video = true;
   1746   JsepSessionDescription* offer = CreateRemoteOffer(
   1747       options, cricket::SEC_DISABLED);
   1748   ASSERT_TRUE(offer != NULL);
   1749   VerifyNoCryptoParams(offer->description(), false);
   1750   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1751   // the offer.
   1752   SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
   1753   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
   1754   ASSERT_TRUE(offer != NULL);
   1755   SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
   1756 }
   1757 
   1758 // Test that we return a failure when applying a local answer that doesn't have
   1759 // cryptos enabled when DTLS is off.
   1760 TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
   1761   Init();
   1762   SessionDescriptionInterface* offer = NULL;
   1763   SessionDescriptionInterface* answer = NULL;
   1764   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
   1765   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1766   // the offer.
   1767   SetRemoteDescriptionWithoutError(offer);
   1768   SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
   1769 }
   1770 
   1771 // Test we will return fail when apply an remote answer that doesn't have
   1772 // crypto enabled when DTLS is off.
   1773 TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
   1774   Init();
   1775   SessionDescriptionInterface* offer = NULL;
   1776   SessionDescriptionInterface* answer = NULL;
   1777   CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
   1778   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1779   // the offer.
   1780   SetLocalDescriptionWithoutError(offer);
   1781   SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
   1782 }
   1783 
   1784 // Test that we accept an offer with a DTLS fingerprint when DTLS is on
   1785 // and that we return an answer with a DTLS fingerprint.
   1786 TEST_P(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
   1787   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   1788   SendAudioVideoStream1();
   1789   InitWithDtls(GetParam());
   1790   SetFactoryDtlsSrtp();
   1791   cricket::MediaSessionOptions options;
   1792   options.recv_video = true;
   1793   JsepSessionDescription* offer =
   1794       CreateRemoteOffer(options, cricket::SEC_DISABLED);
   1795   ASSERT_TRUE(offer != NULL);
   1796   VerifyFingerprintStatus(offer->description(), true);
   1797   VerifyNoCryptoParams(offer->description(), true);
   1798 
   1799   // SetRemoteDescription will take the ownership of the offer.
   1800   SetRemoteDescriptionWithoutError(offer);
   1801 
   1802   // Verify that we get a crypto fingerprint in the answer.
   1803   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1804   ASSERT_TRUE(answer != NULL);
   1805   VerifyFingerprintStatus(answer->description(), true);
   1806   // Check that we don't have an a=crypto line in the answer.
   1807   VerifyNoCryptoParams(answer->description(), true);
   1808 
   1809   // Now set the local description, which should work, even without a=crypto.
   1810   SetLocalDescriptionWithoutError(answer);
   1811 }
   1812 
   1813 // Test that we set a local offer with a DTLS fingerprint when DTLS is on
   1814 // and then we accept a remote answer with a DTLS fingerprint successfully.
   1815 TEST_P(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
   1816   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   1817   SendAudioVideoStream1();
   1818   InitWithDtls(GetParam());
   1819   SetFactoryDtlsSrtp();
   1820 
   1821   // Verify that we get a crypto fingerprint in the answer.
   1822   SessionDescriptionInterface* offer = CreateOffer();
   1823   ASSERT_TRUE(offer != NULL);
   1824   VerifyFingerprintStatus(offer->description(), true);
   1825   // Check that we don't have an a=crypto line in the offer.
   1826   VerifyNoCryptoParams(offer->description(), true);
   1827 
   1828   // Now set the local description, which should work, even without a=crypto.
   1829   SetLocalDescriptionWithoutError(offer);
   1830 
   1831   cricket::MediaSessionOptions options;
   1832   options.recv_video = true;
   1833   JsepSessionDescription* answer =
   1834       CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
   1835   ASSERT_TRUE(answer != NULL);
   1836   VerifyFingerprintStatus(answer->description(), true);
   1837   VerifyNoCryptoParams(answer->description(), true);
   1838 
   1839   // SetRemoteDescription will take the ownership of the answer.
   1840   SetRemoteDescriptionWithoutError(answer);
   1841 }
   1842 
   1843 // Test that if we support DTLS and the other side didn't offer a fingerprint,
   1844 // we will fail to set the remote description.
   1845 TEST_P(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
   1846   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   1847   InitWithDtls(GetParam());
   1848   cricket::MediaSessionOptions options;
   1849   options.recv_video = true;
   1850   options.bundle_enabled = true;
   1851   JsepSessionDescription* offer = CreateRemoteOffer(
   1852       options, cricket::SEC_REQUIRED);
   1853   ASSERT_TRUE(offer != NULL);
   1854   VerifyFingerprintStatus(offer->description(), false);
   1855   VerifyCryptoParams(offer->description());
   1856 
   1857   // SetRemoteDescription will take the ownership of the offer.
   1858   SetRemoteDescriptionOfferExpectError(
   1859       kSdpWithoutDtlsFingerprint, offer);
   1860 
   1861   offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
   1862   // SetLocalDescription will take the ownership of the offer.
   1863   SetLocalDescriptionOfferExpectError(
   1864       kSdpWithoutDtlsFingerprint, offer);
   1865 }
   1866 
   1867 // Test that we return a failure when applying a local answer that doesn't have
   1868 // a DTLS fingerprint when DTLS is required.
   1869 TEST_P(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
   1870   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   1871   InitWithDtls(GetParam());
   1872   SessionDescriptionInterface* offer = NULL;
   1873   SessionDescriptionInterface* answer = NULL;
   1874   CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
   1875 
   1876   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1877   // the offer and answer.
   1878   SetRemoteDescriptionWithoutError(offer);
   1879   SetLocalDescriptionAnswerExpectError(
   1880       kSdpWithoutDtlsFingerprint, answer);
   1881 }
   1882 
   1883 // Test that we return a failure when applying a remote answer that doesn't have
   1884 // a DTLS fingerprint when DTLS is required.
   1885 TEST_P(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
   1886   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   1887   InitWithDtls(GetParam());
   1888   SessionDescriptionInterface* offer = CreateOffer();
   1889   cricket::MediaSessionOptions options;
   1890   options.recv_video = true;
   1891   rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
   1892       CreateRemoteOffer(options, cricket::SEC_ENABLED));
   1893   JsepSessionDescription* answer =
   1894       CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
   1895 
   1896   // SetRemoteDescription and SetLocalDescription will take the ownership of
   1897   // the offer and answer.
   1898   SetLocalDescriptionWithoutError(offer);
   1899   SetRemoteDescriptionAnswerExpectError(
   1900       kSdpWithoutDtlsFingerprint, answer);
   1901 }
   1902 
   1903 // Test that we create a local offer without SDES or DTLS and accept a remote
   1904 // answer without SDES or DTLS when encryption is disabled.
   1905 TEST_P(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
   1906   SendAudioVideoStream1();
   1907   options_.disable_encryption = true;
   1908   InitWithDtls(GetParam());
   1909 
   1910   // Verify that we get a crypto fingerprint in the answer.
   1911   SessionDescriptionInterface* offer = CreateOffer();
   1912   ASSERT_TRUE(offer != NULL);
   1913   VerifyFingerprintStatus(offer->description(), false);
   1914   // Check that we don't have an a=crypto line in the offer.
   1915   VerifyNoCryptoParams(offer->description(), false);
   1916 
   1917   // Now set the local description, which should work, even without a=crypto.
   1918   SetLocalDescriptionWithoutError(offer);
   1919 
   1920   cricket::MediaSessionOptions options;
   1921   options.recv_video = true;
   1922   JsepSessionDescription* answer =
   1923       CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
   1924   ASSERT_TRUE(answer != NULL);
   1925   VerifyFingerprintStatus(answer->description(), false);
   1926   VerifyNoCryptoParams(answer->description(), false);
   1927 
   1928   // SetRemoteDescription will take the ownership of the answer.
   1929   SetRemoteDescriptionWithoutError(answer);
   1930 }
   1931 
   1932 // Test that we create a local answer without SDES or DTLS and accept a remote
   1933 // offer without SDES or DTLS when encryption is disabled.
   1934 TEST_P(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
   1935   options_.disable_encryption = true;
   1936   InitWithDtls(GetParam());
   1937 
   1938   cricket::MediaSessionOptions options;
   1939   options.recv_video = true;
   1940   JsepSessionDescription* offer =
   1941       CreateRemoteOffer(options, cricket::SEC_DISABLED);
   1942   ASSERT_TRUE(offer != NULL);
   1943   VerifyFingerprintStatus(offer->description(), false);
   1944   VerifyNoCryptoParams(offer->description(), false);
   1945 
   1946   // SetRemoteDescription will take the ownership of the offer.
   1947   SetRemoteDescriptionWithoutError(offer);
   1948 
   1949   // Verify that we get a crypto fingerprint in the answer.
   1950   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   1951   ASSERT_TRUE(answer != NULL);
   1952   VerifyFingerprintStatus(answer->description(), false);
   1953   // Check that we don't have an a=crypto line in the answer.
   1954   VerifyNoCryptoParams(answer->description(), false);
   1955 
   1956   // Now set the local description, which should work, even without a=crypto.
   1957   SetLocalDescriptionWithoutError(answer);
   1958 }
   1959 
   1960 // Test that we can create and set an answer correctly when different
   1961 // SSL roles have been negotiated for different transports.
   1962 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=4525
   1963 TEST_P(WebRtcSessionTest, TestCreateAnswerWithDifferentSslRoles) {
   1964   SendAudioVideoStream1();
   1965   InitWithDtls(GetParam());
   1966   SetFactoryDtlsSrtp();
   1967 
   1968   SessionDescriptionInterface* offer = CreateOffer();
   1969   SetLocalDescriptionWithoutError(offer);
   1970 
   1971   cricket::MediaSessionOptions options;
   1972   options.recv_video = true;
   1973 
   1974   // First, negotiate different SSL roles.
   1975   SessionDescriptionInterface* answer =
   1976       CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
   1977   TransportInfo* audio_transport_info =
   1978       answer->description()->GetTransportInfoByName("audio");
   1979   audio_transport_info->description.connection_role =
   1980       cricket::CONNECTIONROLE_ACTIVE;
   1981   TransportInfo* video_transport_info =
   1982       answer->description()->GetTransportInfoByName("video");
   1983   video_transport_info->description.connection_role =
   1984       cricket::CONNECTIONROLE_PASSIVE;
   1985   SetRemoteDescriptionWithoutError(answer);
   1986 
   1987   // Now create an offer in the reverse direction, and ensure the initial
   1988   // offerer responds with an answer with correct SSL roles.
   1989   offer = CreateRemoteOfferWithVersion(options, cricket::SEC_DISABLED,
   1990                                        kSessionVersion,
   1991                                        session_->remote_description());
   1992   SetRemoteDescriptionWithoutError(offer);
   1993 
   1994   answer = CreateAnswer(nullptr);
   1995   audio_transport_info = answer->description()->GetTransportInfoByName("audio");
   1996   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
   1997             audio_transport_info->description.connection_role);
   1998   video_transport_info = answer->description()->GetTransportInfoByName("video");
   1999   EXPECT_EQ(cricket::CONNECTIONROLE_ACTIVE,
   2000             video_transport_info->description.connection_role);
   2001   SetLocalDescriptionWithoutError(answer);
   2002 
   2003   // Lastly, start BUNDLE-ing on "audio", expecting that the "passive" role of
   2004   // audio is transferred over to video in the answer that completes the BUNDLE
   2005   // negotiation.
   2006   options.bundle_enabled = true;
   2007   offer = CreateRemoteOfferWithVersion(options, cricket::SEC_DISABLED,
   2008                                        kSessionVersion,
   2009                                        session_->remote_description());
   2010   SetRemoteDescriptionWithoutError(offer);
   2011   answer = CreateAnswer(nullptr);
   2012   audio_transport_info = answer->description()->GetTransportInfoByName("audio");
   2013   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
   2014             audio_transport_info->description.connection_role);
   2015   video_transport_info = answer->description()->GetTransportInfoByName("video");
   2016   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
   2017             video_transport_info->description.connection_role);
   2018   SetLocalDescriptionWithoutError(answer);
   2019 }
   2020 
   2021 TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
   2022   Init();
   2023   SendNothing();
   2024   // SetLocalDescription take ownership of offer.
   2025   SessionDescriptionInterface* offer = CreateOffer();
   2026   SetLocalDescriptionWithoutError(offer);
   2027 
   2028   // SetLocalDescription take ownership of offer.
   2029   SessionDescriptionInterface* offer2 = CreateOffer();
   2030   SetLocalDescriptionWithoutError(offer2);
   2031 }
   2032 
   2033 TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
   2034   Init();
   2035   SendNothing();
   2036   // SetLocalDescription take ownership of offer.
   2037   SessionDescriptionInterface* offer = CreateOffer();
   2038   SetRemoteDescriptionWithoutError(offer);
   2039 
   2040   SessionDescriptionInterface* offer2 = CreateOffer();
   2041   SetRemoteDescriptionWithoutError(offer2);
   2042 }
   2043 
   2044 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
   2045   Init();
   2046   SendNothing();
   2047   SessionDescriptionInterface* offer = CreateOffer();
   2048   SetLocalDescriptionWithoutError(offer);
   2049   offer = CreateOffer();
   2050   SetRemoteDescriptionOfferExpectError("Called in wrong state: STATE_SENTOFFER",
   2051                                        offer);
   2052 }
   2053 
   2054 TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
   2055   Init();
   2056   SendNothing();
   2057   SessionDescriptionInterface* offer = CreateOffer();
   2058   SetRemoteDescriptionWithoutError(offer);
   2059   offer = CreateOffer();
   2060   SetLocalDescriptionOfferExpectError(
   2061       "Called in wrong state: STATE_RECEIVEDOFFER", offer);
   2062 }
   2063 
   2064 TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
   2065   Init();
   2066   SendNothing();
   2067   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2068   SetRemoteDescriptionExpectState(offer, WebRtcSession::STATE_RECEIVEDOFFER);
   2069 
   2070   JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
   2071       CreateAnswer(NULL));
   2072   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
   2073   SetLocalDescriptionExpectState(pranswer, WebRtcSession::STATE_SENTPRANSWER);
   2074 
   2075   SendAudioVideoStream1();
   2076   JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
   2077       CreateAnswer(NULL));
   2078   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
   2079 
   2080   SetLocalDescriptionExpectState(pranswer2, WebRtcSession::STATE_SENTPRANSWER);
   2081 
   2082   SendAudioVideoStream2();
   2083   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2084   SetLocalDescriptionExpectState(answer, WebRtcSession::STATE_INPROGRESS);
   2085 }
   2086 
   2087 TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
   2088   Init();
   2089   SendNothing();
   2090   SessionDescriptionInterface* offer = CreateOffer();
   2091   SetLocalDescriptionExpectState(offer, WebRtcSession::STATE_SENTOFFER);
   2092 
   2093   JsepSessionDescription* pranswer =
   2094       CreateRemoteAnswer(session_->local_description());
   2095   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
   2096 
   2097   SetRemoteDescriptionExpectState(pranswer,
   2098                                   WebRtcSession::STATE_RECEIVEDPRANSWER);
   2099 
   2100   SendAudioVideoStream1();
   2101   JsepSessionDescription* pranswer2 =
   2102       CreateRemoteAnswer(session_->local_description());
   2103   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
   2104 
   2105   SetRemoteDescriptionExpectState(pranswer2,
   2106                                   WebRtcSession::STATE_RECEIVEDPRANSWER);
   2107 
   2108   SendAudioVideoStream2();
   2109   SessionDescriptionInterface* answer =
   2110       CreateRemoteAnswer(session_->local_description());
   2111   SetRemoteDescriptionExpectState(answer, WebRtcSession::STATE_INPROGRESS);
   2112 }
   2113 
   2114 TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
   2115   Init();
   2116   SendNothing();
   2117   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2118 
   2119   SessionDescriptionInterface* answer =
   2120       CreateRemoteAnswer(offer.get());
   2121   SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
   2122                                        answer);
   2123 }
   2124 
   2125 TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
   2126   Init();
   2127   SendNothing();
   2128   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2129 
   2130   SessionDescriptionInterface* answer =
   2131       CreateRemoteAnswer(offer.get());
   2132   SetRemoteDescriptionAnswerExpectError(
   2133       "Called in wrong state: STATE_INIT", answer);
   2134 }
   2135 
   2136 TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
   2137   Init();
   2138   SendAudioVideoStream1();
   2139 
   2140   cricket::Candidate candidate;
   2141   candidate.set_component(1);
   2142   JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
   2143 
   2144   // Fail since we have not set a remote description.
   2145   EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
   2146 
   2147   SessionDescriptionInterface* offer = CreateOffer();
   2148   SetLocalDescriptionWithoutError(offer);
   2149 
   2150   // Fail since we have not set a remote description.
   2151   EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
   2152 
   2153   SessionDescriptionInterface* answer = CreateRemoteAnswer(
   2154       session_->local_description());
   2155   SetRemoteDescriptionWithoutError(answer);
   2156 
   2157   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
   2158   candidate.set_component(2);
   2159   JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
   2160   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
   2161 
   2162   // Verifying the candidates are copied properly from internal vector.
   2163   const SessionDescriptionInterface* remote_desc =
   2164       session_->remote_description();
   2165   ASSERT_TRUE(remote_desc != NULL);
   2166   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   2167   const IceCandidateCollection* candidates =
   2168       remote_desc->candidates(kMediaContentIndex0);
   2169   ASSERT_EQ(2u, candidates->count());
   2170   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   2171   EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
   2172   EXPECT_EQ(1, candidates->at(0)->candidate().component());
   2173   EXPECT_EQ(2, candidates->at(1)->candidate().component());
   2174 
   2175   // |ice_candidate3| is identical to |ice_candidate2|.  It can be added
   2176   // successfully, but the total count of candidates will not increase.
   2177   candidate.set_component(2);
   2178   JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
   2179   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
   2180   ASSERT_EQ(2u, candidates->count());
   2181 
   2182   JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
   2183   EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
   2184 }
   2185 
   2186 // Test that a remote candidate is added to the remote session description and
   2187 // that it is retained if the remote session description is changed.
   2188 TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
   2189   Init();
   2190   cricket::Candidate candidate1;
   2191   candidate1.set_component(1);
   2192   JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
   2193                                   candidate1);
   2194   SendAudioVideoStream1();
   2195   CreateAndSetRemoteOfferAndLocalAnswer();
   2196 
   2197   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
   2198   const SessionDescriptionInterface* remote_desc =
   2199       session_->remote_description();
   2200   ASSERT_TRUE(remote_desc != NULL);
   2201   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   2202   const IceCandidateCollection* candidates =
   2203       remote_desc->candidates(kMediaContentIndex0);
   2204   ASSERT_EQ(1u, candidates->count());
   2205   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   2206 
   2207   // Update the RemoteSessionDescription with a new session description and
   2208   // a candidate and check that the new remote session description contains both
   2209   // candidates.
   2210   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2211   cricket::Candidate candidate2;
   2212   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
   2213                                   candidate2);
   2214   EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
   2215   SetRemoteDescriptionWithoutError(offer);
   2216 
   2217   remote_desc = session_->remote_description();
   2218   ASSERT_TRUE(remote_desc != NULL);
   2219   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   2220   candidates = remote_desc->candidates(kMediaContentIndex0);
   2221   ASSERT_EQ(2u, candidates->count());
   2222   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   2223   // Username and password have be updated with the TransportInfo of the
   2224   // SessionDescription, won't be equal to the original one.
   2225   candidate2.set_username(candidates->at(0)->candidate().username());
   2226   candidate2.set_password(candidates->at(0)->candidate().password());
   2227   EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
   2228   EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
   2229   // No need to verify the username and password.
   2230   candidate1.set_username(candidates->at(1)->candidate().username());
   2231   candidate1.set_password(candidates->at(1)->candidate().password());
   2232   EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
   2233 
   2234   // Test that the candidate is ignored if we can add the same candidate again.
   2235   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
   2236 }
   2237 
   2238 // Test that local candidates are added to the local session description and
   2239 // that they are retained if the local session description is changed.
   2240 TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
   2241   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   2242   Init();
   2243   SendAudioVideoStream1();
   2244   CreateAndSetRemoteOfferAndLocalAnswer();
   2245 
   2246   const SessionDescriptionInterface* local_desc = session_->local_description();
   2247   const IceCandidateCollection* candidates =
   2248       local_desc->candidates(kMediaContentIndex0);
   2249   ASSERT_TRUE(candidates != NULL);
   2250   EXPECT_EQ(0u, candidates->count());
   2251 
   2252   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   2253 
   2254   local_desc = session_->local_description();
   2255   candidates = local_desc->candidates(kMediaContentIndex0);
   2256   ASSERT_TRUE(candidates != NULL);
   2257   EXPECT_LT(0u, candidates->count());
   2258   candidates = local_desc->candidates(1);
   2259   ASSERT_TRUE(candidates != NULL);
   2260   EXPECT_EQ(0u, candidates->count());
   2261 
   2262   // Update the session descriptions.
   2263   SendAudioVideoStream1();
   2264   CreateAndSetRemoteOfferAndLocalAnswer();
   2265 
   2266   local_desc = session_->local_description();
   2267   candidates = local_desc->candidates(kMediaContentIndex0);
   2268   ASSERT_TRUE(candidates != NULL);
   2269   EXPECT_LT(0u, candidates->count());
   2270   candidates = local_desc->candidates(1);
   2271   ASSERT_TRUE(candidates != NULL);
   2272   EXPECT_EQ(0u, candidates->count());
   2273 }
   2274 
   2275 // Test that we can set a remote session description with remote candidates.
   2276 TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
   2277   Init();
   2278 
   2279   cricket::Candidate candidate1;
   2280   candidate1.set_component(1);
   2281   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
   2282                                  candidate1);
   2283   SendAudioVideoStream1();
   2284   SessionDescriptionInterface* offer = CreateOffer();
   2285 
   2286   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   2287   SetRemoteDescriptionWithoutError(offer);
   2288 
   2289   const SessionDescriptionInterface* remote_desc =
   2290       session_->remote_description();
   2291   ASSERT_TRUE(remote_desc != NULL);
   2292   ASSERT_EQ(2u, remote_desc->number_of_mediasections());
   2293   const IceCandidateCollection* candidates =
   2294       remote_desc->candidates(kMediaContentIndex0);
   2295   ASSERT_EQ(1u, candidates->count());
   2296   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
   2297 
   2298   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2299   SetLocalDescriptionWithoutError(answer);
   2300 }
   2301 
   2302 // Test that offers and answers contains ice candidates when Ice candidates have
   2303 // been gathered.
   2304 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
   2305   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   2306   Init();
   2307   SendAudioVideoStream1();
   2308   // Ice is started but candidates are not provided until SetLocalDescription
   2309   // is called.
   2310   EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
   2311   EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
   2312   CreateAndSetRemoteOfferAndLocalAnswer();
   2313   // Wait until at least one local candidate has been collected.
   2314   EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
   2315                    kIceCandidatesTimeout);
   2316 
   2317   rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
   2318 
   2319   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
   2320   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
   2321 
   2322   SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
   2323   SetRemoteDescriptionWithoutError(remote_offer);
   2324   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2325   ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
   2326   EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
   2327   SetLocalDescriptionWithoutError(answer);
   2328 }
   2329 
   2330 // Verifies TransportProxy and media channels are created with content names
   2331 // present in the SessionDescription.
   2332 TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
   2333   Init();
   2334   SendAudioVideoStream1();
   2335   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2336 
   2337   // CreateOffer creates session description with the content names "audio" and
   2338   // "video". Goal is to modify these content names and verify transport
   2339   // channels
   2340   // in the WebRtcSession, as channels are created with the content names
   2341   // present in SDP.
   2342   std::string sdp;
   2343   EXPECT_TRUE(offer->ToString(&sdp));
   2344   const std::string kAudioMid = "a=mid:audio";
   2345   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
   2346   const std::string kVideoMid = "a=mid:video";
   2347   const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
   2348 
   2349   // Replacing |audio| with |audio_content_name|.
   2350   rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
   2351                              kAudioMidReplaceStr.c_str(),
   2352                              kAudioMidReplaceStr.length(),
   2353                              &sdp);
   2354   // Replacing |video| with |video_content_name|.
   2355   rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
   2356                              kVideoMidReplaceStr.c_str(),
   2357                              kVideoMidReplaceStr.length(),
   2358                              &sdp);
   2359 
   2360   SessionDescriptionInterface* modified_offer =
   2361       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2362 
   2363   SetRemoteDescriptionWithoutError(modified_offer);
   2364 
   2365   SessionDescriptionInterface* answer =
   2366       CreateAnswer(NULL);
   2367   SetLocalDescriptionWithoutError(answer);
   2368 
   2369   cricket::TransportChannel* voice_transport_channel =
   2370       session_->voice_rtp_transport_channel();
   2371   EXPECT_TRUE(voice_transport_channel != NULL);
   2372   EXPECT_EQ(voice_transport_channel->transport_name(), "audio_content_name");
   2373   cricket::TransportChannel* video_transport_channel =
   2374       session_->video_rtp_transport_channel();
   2375   EXPECT_TRUE(video_transport_channel != NULL);
   2376   EXPECT_EQ(video_transport_channel->transport_name(), "video_content_name");
   2377   EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
   2378   EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
   2379 }
   2380 
   2381 // Test that an offer contains the correct media content descriptions based on
   2382 // the send streams when no constraints have been set.
   2383 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
   2384   Init();
   2385   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2386 
   2387   ASSERT_TRUE(offer != NULL);
   2388   const cricket::ContentInfo* content =
   2389       cricket::GetFirstAudioContent(offer->description());
   2390   EXPECT_TRUE(content != NULL);
   2391   content = cricket::GetFirstVideoContent(offer->description());
   2392   EXPECT_TRUE(content == NULL);
   2393 }
   2394 
   2395 // Test that an offer contains the correct media content descriptions based on
   2396 // the send streams when no constraints have been set.
   2397 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
   2398   Init();
   2399   // Test Audio only offer.
   2400   SendAudioOnlyStream2();
   2401   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2402 
   2403   const cricket::ContentInfo* content =
   2404       cricket::GetFirstAudioContent(offer->description());
   2405   EXPECT_TRUE(content != NULL);
   2406   content = cricket::GetFirstVideoContent(offer->description());
   2407   EXPECT_TRUE(content == NULL);
   2408 
   2409   // Test Audio / Video offer.
   2410   SendAudioVideoStream1();
   2411   offer.reset(CreateOffer());
   2412   content = cricket::GetFirstAudioContent(offer->description());
   2413   EXPECT_TRUE(content != NULL);
   2414   content = cricket::GetFirstVideoContent(offer->description());
   2415   EXPECT_TRUE(content != NULL);
   2416 }
   2417 
   2418 // Test that an offer contains no media content descriptions if
   2419 // kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
   2420 TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
   2421   Init();
   2422   PeerConnectionInterface::RTCOfferAnswerOptions options;
   2423   options.offer_to_receive_audio = 0;
   2424   options.offer_to_receive_video = 0;
   2425 
   2426   rtc::scoped_ptr<SessionDescriptionInterface> offer(
   2427       CreateOffer(options));
   2428 
   2429   ASSERT_TRUE(offer != NULL);
   2430   const cricket::ContentInfo* content =
   2431       cricket::GetFirstAudioContent(offer->description());
   2432   EXPECT_TRUE(content == NULL);
   2433   content = cricket::GetFirstVideoContent(offer->description());
   2434   EXPECT_TRUE(content == NULL);
   2435 }
   2436 
   2437 // Test that an offer contains only audio media content descriptions if
   2438 // kOfferToReceiveAudio constraints are set to true.
   2439 TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
   2440   Init();
   2441   PeerConnectionInterface::RTCOfferAnswerOptions options;
   2442   options.offer_to_receive_audio =
   2443       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
   2444 
   2445   rtc::scoped_ptr<SessionDescriptionInterface> offer(
   2446         CreateOffer(options));
   2447 
   2448   const cricket::ContentInfo* content =
   2449       cricket::GetFirstAudioContent(offer->description());
   2450   EXPECT_TRUE(content != NULL);
   2451   content = cricket::GetFirstVideoContent(offer->description());
   2452   EXPECT_TRUE(content == NULL);
   2453 }
   2454 
   2455 // Test that an offer contains audio and video media content descriptions if
   2456 // kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
   2457 TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
   2458   Init();
   2459   // Test Audio / Video offer.
   2460   PeerConnectionInterface::RTCOfferAnswerOptions options;
   2461   options.offer_to_receive_audio =
   2462       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
   2463   options.offer_to_receive_video =
   2464       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
   2465 
   2466   rtc::scoped_ptr<SessionDescriptionInterface> offer(
   2467       CreateOffer(options));
   2468 
   2469   const cricket::ContentInfo* content =
   2470       cricket::GetFirstAudioContent(offer->description());
   2471   EXPECT_TRUE(content != NULL);
   2472 
   2473   content = cricket::GetFirstVideoContent(offer->description());
   2474   EXPECT_TRUE(content != NULL);
   2475 
   2476   // Sets constraints to false and verifies that audio/video contents are
   2477   // removed.
   2478   options.offer_to_receive_audio = 0;
   2479   options.offer_to_receive_video = 0;
   2480   offer.reset(CreateOffer(options));
   2481 
   2482   content = cricket::GetFirstAudioContent(offer->description());
   2483   EXPECT_TRUE(content == NULL);
   2484   content = cricket::GetFirstVideoContent(offer->description());
   2485   EXPECT_TRUE(content == NULL);
   2486 }
   2487 
   2488 // Test that an answer can not be created if the last remote description is not
   2489 // an offer.
   2490 TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
   2491   Init();
   2492   SessionDescriptionInterface* offer = CreateOffer();
   2493   SetLocalDescriptionWithoutError(offer);
   2494   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   2495   SetRemoteDescriptionWithoutError(answer);
   2496   EXPECT_TRUE(CreateAnswer(NULL) == NULL);
   2497 }
   2498 
   2499 // Test that an answer contains the correct media content descriptions when no
   2500 // constraints have been set.
   2501 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
   2502   Init();
   2503   // Create a remote offer with audio and video content.
   2504   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   2505   SetRemoteDescriptionWithoutError(offer.release());
   2506   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2507       CreateAnswer(NULL));
   2508   const cricket::ContentInfo* content =
   2509       cricket::GetFirstAudioContent(answer->description());
   2510   ASSERT_TRUE(content != NULL);
   2511   EXPECT_FALSE(content->rejected);
   2512 
   2513   content = cricket::GetFirstVideoContent(answer->description());
   2514   ASSERT_TRUE(content != NULL);
   2515   EXPECT_FALSE(content->rejected);
   2516 }
   2517 
   2518 // Test that an answer contains the correct media content descriptions when no
   2519 // constraints have been set and the offer only contain audio.
   2520 TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
   2521   Init();
   2522   // Create a remote offer with audio only.
   2523   cricket::MediaSessionOptions options;
   2524 
   2525   rtc::scoped_ptr<JsepSessionDescription> offer(
   2526       CreateRemoteOffer(options));
   2527   ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
   2528   ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
   2529 
   2530   SetRemoteDescriptionWithoutError(offer.release());
   2531   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2532       CreateAnswer(NULL));
   2533   const cricket::ContentInfo* content =
   2534       cricket::GetFirstAudioContent(answer->description());
   2535   ASSERT_TRUE(content != NULL);
   2536   EXPECT_FALSE(content->rejected);
   2537 
   2538   EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
   2539 }
   2540 
   2541 // Test that an answer contains the correct media content descriptions when no
   2542 // constraints have been set.
   2543 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
   2544   Init();
   2545   // Create a remote offer with audio and video content.
   2546   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   2547   SetRemoteDescriptionWithoutError(offer.release());
   2548   // Test with a stream with tracks.
   2549   SendAudioVideoStream1();
   2550   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2551       CreateAnswer(NULL));
   2552   const cricket::ContentInfo* content =
   2553       cricket::GetFirstAudioContent(answer->description());
   2554   ASSERT_TRUE(content != NULL);
   2555   EXPECT_FALSE(content->rejected);
   2556 
   2557   content = cricket::GetFirstVideoContent(answer->description());
   2558   ASSERT_TRUE(content != NULL);
   2559   EXPECT_FALSE(content->rejected);
   2560 }
   2561 
   2562 // Test that an answer contains the correct media content descriptions when
   2563 // constraints have been set but no stream is sent.
   2564 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
   2565   Init();
   2566   // Create a remote offer with audio and video content.
   2567   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   2568   SetRemoteDescriptionWithoutError(offer.release());
   2569 
   2570   webrtc::FakeConstraints constraints_no_receive;
   2571   constraints_no_receive.SetMandatoryReceiveAudio(false);
   2572   constraints_no_receive.SetMandatoryReceiveVideo(false);
   2573 
   2574   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2575       CreateAnswer(&constraints_no_receive));
   2576   const cricket::ContentInfo* content =
   2577       cricket::GetFirstAudioContent(answer->description());
   2578   ASSERT_TRUE(content != NULL);
   2579   EXPECT_TRUE(content->rejected);
   2580 
   2581   content = cricket::GetFirstVideoContent(answer->description());
   2582   ASSERT_TRUE(content != NULL);
   2583   EXPECT_TRUE(content->rejected);
   2584 }
   2585 
   2586 // Test that an answer contains the correct media content descriptions when
   2587 // constraints have been set and streams are sent.
   2588 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
   2589   Init();
   2590   // Create a remote offer with audio and video content.
   2591   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   2592   SetRemoteDescriptionWithoutError(offer.release());
   2593 
   2594   webrtc::FakeConstraints constraints_no_receive;
   2595   constraints_no_receive.SetMandatoryReceiveAudio(false);
   2596   constraints_no_receive.SetMandatoryReceiveVideo(false);
   2597 
   2598   // Test with a stream with tracks.
   2599   SendAudioVideoStream1();
   2600   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2601       CreateAnswer(&constraints_no_receive));
   2602 
   2603   // TODO(perkj): Should the direction be set to SEND_ONLY?
   2604   const cricket::ContentInfo* content =
   2605       cricket::GetFirstAudioContent(answer->description());
   2606   ASSERT_TRUE(content != NULL);
   2607   EXPECT_FALSE(content->rejected);
   2608 
   2609   // TODO(perkj): Should the direction be set to SEND_ONLY?
   2610   content = cricket::GetFirstVideoContent(answer->description());
   2611   ASSERT_TRUE(content != NULL);
   2612   EXPECT_FALSE(content->rejected);
   2613 }
   2614 
   2615 TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
   2616   AddCNCodecs();
   2617   Init();
   2618   PeerConnectionInterface::RTCOfferAnswerOptions options;
   2619   options.offer_to_receive_audio =
   2620       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
   2621   options.voice_activity_detection = false;
   2622 
   2623   rtc::scoped_ptr<SessionDescriptionInterface> offer(
   2624       CreateOffer(options));
   2625 
   2626   const cricket::ContentInfo* content =
   2627       cricket::GetFirstAudioContent(offer->description());
   2628   EXPECT_TRUE(content != NULL);
   2629   EXPECT_TRUE(VerifyNoCNCodecs(content));
   2630 }
   2631 
   2632 TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
   2633   AddCNCodecs();
   2634   Init();
   2635   // Create a remote offer with audio and video content.
   2636   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   2637   SetRemoteDescriptionWithoutError(offer.release());
   2638 
   2639   webrtc::FakeConstraints constraints;
   2640   constraints.SetOptionalVAD(false);
   2641   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   2642       CreateAnswer(&constraints));
   2643   const cricket::ContentInfo* content =
   2644       cricket::GetFirstAudioContent(answer->description());
   2645   ASSERT_TRUE(content != NULL);
   2646   EXPECT_TRUE(VerifyNoCNCodecs(content));
   2647 }
   2648 
   2649 // This test verifies the call setup when remote answer with audio only and
   2650 // later updates with video.
   2651 TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
   2652   Init();
   2653   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
   2654   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
   2655 
   2656   SendAudioVideoStream1();
   2657   SessionDescriptionInterface* offer = CreateOffer();
   2658 
   2659   cricket::MediaSessionOptions options;
   2660   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
   2661 
   2662   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
   2663   // and answer;
   2664   SetLocalDescriptionWithoutError(offer);
   2665   SetRemoteDescriptionWithoutError(answer);
   2666 
   2667   video_channel_ = media_engine_->GetVideoChannel(0);
   2668   voice_channel_ = media_engine_->GetVoiceChannel(0);
   2669 
   2670   ASSERT_TRUE(video_channel_ == NULL);
   2671 
   2672   ASSERT_EQ(0u, voice_channel_->recv_streams().size());
   2673   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   2674   EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
   2675 
   2676   // Let the remote end update the session descriptions, with Audio and Video.
   2677   SendAudioVideoStream2();
   2678   CreateAndSetRemoteOfferAndLocalAnswer();
   2679 
   2680   video_channel_ = media_engine_->GetVideoChannel(0);
   2681   voice_channel_ = media_engine_->GetVoiceChannel(0);
   2682 
   2683   ASSERT_TRUE(video_channel_ != NULL);
   2684   ASSERT_TRUE(voice_channel_ != NULL);
   2685 
   2686   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   2687   ASSERT_EQ(1u, video_channel_->send_streams().size());
   2688   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
   2689   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
   2690   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   2691   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   2692   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   2693   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   2694 
   2695   // Change session back to audio only.
   2696   SendAudioOnlyStream2();
   2697   CreateAndSetRemoteOfferAndLocalAnswer();
   2698 
   2699   EXPECT_EQ(0u, video_channel_->recv_streams().size());
   2700   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   2701   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   2702   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   2703   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   2704 }
   2705 
   2706 // This test verifies the call setup when remote answer with video only and
   2707 // later updates with audio.
   2708 TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
   2709   Init();
   2710   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
   2711   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
   2712   SendAudioVideoStream1();
   2713   SessionDescriptionInterface* offer = CreateOffer();
   2714 
   2715   cricket::MediaSessionOptions options;
   2716   options.recv_audio = false;
   2717   options.recv_video = true;
   2718   SessionDescriptionInterface* answer = CreateRemoteAnswer(
   2719       offer, options, cricket::SEC_ENABLED);
   2720 
   2721   // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
   2722   // and answer.
   2723   SetLocalDescriptionWithoutError(offer);
   2724   SetRemoteDescriptionWithoutError(answer);
   2725 
   2726   video_channel_ = media_engine_->GetVideoChannel(0);
   2727   voice_channel_ = media_engine_->GetVoiceChannel(0);
   2728 
   2729   ASSERT_TRUE(voice_channel_ == NULL);
   2730   ASSERT_TRUE(video_channel_ != NULL);
   2731 
   2732   EXPECT_EQ(0u, video_channel_->recv_streams().size());
   2733   ASSERT_EQ(1u, video_channel_->send_streams().size());
   2734   EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
   2735 
   2736   // Update the session descriptions, with Audio and Video.
   2737   SendAudioVideoStream2();
   2738   CreateAndSetRemoteOfferAndLocalAnswer();
   2739 
   2740   voice_channel_ = media_engine_->GetVoiceChannel(0);
   2741   ASSERT_TRUE(voice_channel_ != NULL);
   2742 
   2743   ASSERT_EQ(1u, voice_channel_->recv_streams().size());
   2744   ASSERT_EQ(1u, voice_channel_->send_streams().size());
   2745   EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
   2746   EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
   2747 
   2748   // Change session back to video only.
   2749   SendVideoOnlyStream2();
   2750   CreateAndSetRemoteOfferAndLocalAnswer();
   2751 
   2752   video_channel_ = media_engine_->GetVideoChannel(0);
   2753   voice_channel_ = media_engine_->GetVoiceChannel(0);
   2754 
   2755   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   2756   EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
   2757   ASSERT_EQ(1u, video_channel_->send_streams().size());
   2758   EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
   2759 }
   2760 
   2761 TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
   2762   Init();
   2763   SendAudioVideoStream1();
   2764   scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2765   VerifyCryptoParams(offer->description());
   2766   SetRemoteDescriptionWithoutError(offer.release());
   2767   scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   2768   VerifyCryptoParams(answer->description());
   2769 }
   2770 
   2771 TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
   2772   options_.disable_encryption = true;
   2773   Init();
   2774   SendAudioVideoStream1();
   2775   scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2776   VerifyNoCryptoParams(offer->description(), false);
   2777 }
   2778 
   2779 TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
   2780   Init();
   2781   VerifyAnswerFromNonCryptoOffer();
   2782 }
   2783 
   2784 TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
   2785   Init();
   2786   VerifyAnswerFromCryptoOffer();
   2787 }
   2788 
   2789 // This test verifies that setLocalDescription fails if
   2790 // no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
   2791 TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
   2792   Init();
   2793   SendAudioVideoStream1();
   2794   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2795 
   2796   std::string sdp;
   2797   RemoveIceUfragPwdLines(offer.get(), &sdp);
   2798   SessionDescriptionInterface* modified_offer =
   2799     CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2800   SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
   2801 }
   2802 
   2803 // This test verifies that setRemoteDescription fails if
   2804 // no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
   2805 TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
   2806   Init();
   2807   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
   2808   std::string sdp;
   2809   RemoveIceUfragPwdLines(offer.get(), &sdp);
   2810   SessionDescriptionInterface* modified_offer =
   2811     CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2812   SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
   2813 }
   2814 
   2815 // This test verifies that setLocalDescription fails if local offer has
   2816 // too short ice ufrag and pwd strings.
   2817 TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
   2818   Init();
   2819   SendAudioVideoStream1();
   2820   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   2821 
   2822   std::string sdp;
   2823   // Modifying ice ufrag and pwd in local offer with strings smaller than the
   2824   // recommended values of 4 and 22 bytes respectively.
   2825   ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
   2826   SessionDescriptionInterface* modified_offer =
   2827       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2828   std::string error;
   2829   EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
   2830 
   2831   // Test with string greater than 256.
   2832   sdp.clear();
   2833   ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
   2834                          &sdp);
   2835   modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
   2836                                             NULL);
   2837   EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
   2838 }
   2839 
   2840 // This test verifies that setRemoteDescription fails if remote offer has
   2841 // too short ice ufrag and pwd strings.
   2842 TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
   2843   Init();
   2844   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
   2845   std::string sdp;
   2846   // Modifying ice ufrag and pwd in remote offer with strings smaller than the
   2847   // recommended values of 4 and 22 bytes respectively.
   2848   ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
   2849   SessionDescriptionInterface* modified_offer =
   2850      CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2851   std::string error;
   2852   EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
   2853 
   2854   sdp.clear();
   2855   ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
   2856                          &sdp);
   2857   modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
   2858                                             NULL);
   2859   EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
   2860 }
   2861 
   2862 // Test that if the remote offer indicates the peer requested ICE restart (via
   2863 // a new ufrag or pwd), the old ICE candidates are not copied, and vice versa.
   2864 TEST_F(WebRtcSessionTest, TestSetRemoteOfferWithIceRestart) {
   2865   Init();
   2866   scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
   2867 
   2868   // Create the first offer.
   2869   std::string sdp;
   2870   ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
   2871                          "abcdefghijklmnopqrstuvwx", &sdp);
   2872   SessionDescriptionInterface* offer1 =
   2873       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2874   cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
   2875                                 0, "", "", "relay", 0, "");
   2876   JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
   2877                                   candidate1);
   2878   EXPECT_TRUE(offer1->AddCandidate(&ice_candidate1));
   2879   SetRemoteDescriptionWithoutError(offer1);
   2880   EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
   2881 
   2882   // The second offer has the same ufrag and pwd but different address.
   2883   sdp.clear();
   2884   ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
   2885                          "abcdefghijklmnopqrstuvwx", &sdp);
   2886   SessionDescriptionInterface* offer2 =
   2887       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2888   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
   2889   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
   2890                                   candidate1);
   2891   EXPECT_TRUE(offer2->AddCandidate(&ice_candidate2));
   2892   SetRemoteDescriptionWithoutError(offer2);
   2893   EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
   2894 
   2895   // The third offer has a different ufrag and different address.
   2896   sdp.clear();
   2897   ModifyIceUfragPwdLines(offer.get(), "0123456789012333",
   2898                          "abcdefghijklmnopqrstuvwx", &sdp);
   2899   SessionDescriptionInterface* offer3 =
   2900       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2901   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
   2902   JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
   2903                                   candidate1);
   2904   EXPECT_TRUE(offer3->AddCandidate(&ice_candidate3));
   2905   SetRemoteDescriptionWithoutError(offer3);
   2906   EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
   2907 
   2908   // The fourth offer has no candidate but a different ufrag/pwd.
   2909   sdp.clear();
   2910   ModifyIceUfragPwdLines(offer.get(), "0123456789012444",
   2911                          "abcdefghijklmnopqrstuvyz", &sdp);
   2912   SessionDescriptionInterface* offer4 =
   2913       CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
   2914   SetRemoteDescriptionWithoutError(offer4);
   2915   EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
   2916 }
   2917 
   2918 // Test that if the remote answer indicates the peer requested ICE restart (via
   2919 // a new ufrag or pwd), the old ICE candidates are not copied, and vice versa.
   2920 TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithIceRestart) {
   2921   Init();
   2922   SessionDescriptionInterface* offer = CreateOffer();
   2923   SetLocalDescriptionWithoutError(offer);
   2924   scoped_ptr<SessionDescriptionInterface> answer(CreateRemoteAnswer(offer));
   2925 
   2926   // Create the first answer.
   2927   std::string sdp;
   2928   ModifyIceUfragPwdLines(answer.get(), "0123456789012345",
   2929                          "abcdefghijklmnopqrstuvwx", &sdp);
   2930   SessionDescriptionInterface* answer1 =
   2931       CreateSessionDescription(JsepSessionDescription::kPrAnswer, sdp, NULL);
   2932   cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
   2933                                 0, "", "", "relay", 0, "");
   2934   JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
   2935                                   candidate1);
   2936   EXPECT_TRUE(answer1->AddCandidate(&ice_candidate1));
   2937   SetRemoteDescriptionWithoutError(answer1);
   2938   EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
   2939 
   2940   // The second answer has the same ufrag and pwd but different address.
   2941   sdp.clear();
   2942   ModifyIceUfragPwdLines(answer.get(), "0123456789012345",
   2943                          "abcdefghijklmnopqrstuvwx", &sdp);
   2944   SessionDescriptionInterface* answer2 =
   2945       CreateSessionDescription(JsepSessionDescription::kPrAnswer, sdp, NULL);
   2946   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
   2947   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
   2948                                   candidate1);
   2949   EXPECT_TRUE(answer2->AddCandidate(&ice_candidate2));
   2950   SetRemoteDescriptionWithoutError(answer2);
   2951   EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
   2952 
   2953   // The third answer has a different ufrag and different address.
   2954   sdp.clear();
   2955   ModifyIceUfragPwdLines(answer.get(), "0123456789012333",
   2956                          "abcdefghijklmnopqrstuvwx", &sdp);
   2957   SessionDescriptionInterface* answer3 =
   2958       CreateSessionDescription(JsepSessionDescription::kPrAnswer, sdp, NULL);
   2959   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
   2960   JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
   2961                                   candidate1);
   2962   EXPECT_TRUE(answer3->AddCandidate(&ice_candidate3));
   2963   SetRemoteDescriptionWithoutError(answer3);
   2964   EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
   2965 
   2966   // The fourth answer has no candidate but a different ufrag/pwd.
   2967   sdp.clear();
   2968   ModifyIceUfragPwdLines(answer.get(), "0123456789012444",
   2969                          "abcdefghijklmnopqrstuvyz", &sdp);
   2970   SessionDescriptionInterface* offer4 =
   2971       CreateSessionDescription(JsepSessionDescription::kPrAnswer, sdp, NULL);
   2972   SetRemoteDescriptionWithoutError(offer4);
   2973   EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
   2974 }
   2975 
   2976 // Test that candidates sent to the "video" transport do not get pushed down to
   2977 // the "audio" transport channel when bundling.
   2978 TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
   2979   AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   2980 
   2981   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
   2982   SendAudioVideoStream1();
   2983 
   2984   PeerConnectionInterface::RTCOfferAnswerOptions options;
   2985   options.use_rtp_mux = true;
   2986 
   2987   SessionDescriptionInterface* offer = CreateRemoteOffer();
   2988   SetRemoteDescriptionWithoutError(offer);
   2989 
   2990   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   2991   SetLocalDescriptionWithoutError(answer);
   2992 
   2993   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   2994             session_->video_rtp_transport_channel());
   2995 
   2996   cricket::BaseChannel* voice_channel = session_->voice_channel();
   2997   ASSERT(voice_channel != NULL);
   2998 
   2999   // Checks if one of the transport channels contains a connection using a given
   3000   // port.
   3001   auto connection_with_remote_port = [this, voice_channel](int port) {
   3002     SessionStats stats;
   3003     session_->GetChannelTransportStats(voice_channel, &stats);
   3004     for (auto& kv : stats.transport_stats) {
   3005       for (auto& chan_stat : kv.second.channel_stats) {
   3006         for (auto& conn_info : chan_stat.connection_infos) {
   3007           if (conn_info.remote_candidate.address().port() == port) {
   3008             return true;
   3009           }
   3010         }
   3011       }
   3012     }
   3013     return false;
   3014   };
   3015 
   3016   EXPECT_FALSE(connection_with_remote_port(5000));
   3017   EXPECT_FALSE(connection_with_remote_port(5001));
   3018   EXPECT_FALSE(connection_with_remote_port(6000));
   3019 
   3020   // The way the *_WAIT checks work is they only wait if the condition fails,
   3021   // which does not help in the case where state is not changing. This is
   3022   // problematic in this test since we want to verify that adding a video
   3023   // candidate does _not_ change state. So we interleave candidates and assume
   3024   // that messages are executed in the order they were posted.
   3025 
   3026   // First audio candidate.
   3027   cricket::Candidate candidate0;
   3028   candidate0.set_address(rtc::SocketAddress("1.1.1.1", 5000));
   3029   candidate0.set_component(1);
   3030   candidate0.set_protocol("udp");
   3031   JsepIceCandidate ice_candidate0(kMediaContentName0, kMediaContentIndex0,
   3032                                   candidate0);
   3033   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate0));
   3034 
   3035   // Video candidate.
   3036   cricket::Candidate candidate1;
   3037   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
   3038   candidate1.set_component(1);
   3039   candidate1.set_protocol("udp");
   3040   JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
   3041                                   candidate1);
   3042   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
   3043 
   3044   // Second audio candidate.
   3045   cricket::Candidate candidate2;
   3046   candidate2.set_address(rtc::SocketAddress("1.1.1.1", 5001));
   3047   candidate2.set_component(1);
   3048   candidate2.set_protocol("udp");
   3049   JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
   3050                                   candidate2);
   3051   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
   3052 
   3053   EXPECT_TRUE_WAIT(connection_with_remote_port(5000), 1000);
   3054   EXPECT_TRUE_WAIT(connection_with_remote_port(5001), 1000);
   3055 
   3056   // No need here for a _WAIT check since we are checking that state hasn't
   3057   // changed: if this is false we would be doing waits for nothing and if this
   3058   // is true then there will be no messages processed anyways.
   3059   EXPECT_FALSE(connection_with_remote_port(6000));
   3060 }
   3061 
   3062 // kBundlePolicyBalanced BUNDLE policy and answer contains BUNDLE.
   3063 TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
   3064   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
   3065   SendAudioVideoStream1();
   3066 
   3067   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3068   options.use_rtp_mux = true;
   3069 
   3070   SessionDescriptionInterface* offer = CreateOffer(options);
   3071   SetLocalDescriptionWithoutError(offer);
   3072 
   3073   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3074             session_->video_rtp_transport_channel());
   3075 
   3076   SendAudioVideoStream2();
   3077   SessionDescriptionInterface* answer =
   3078       CreateRemoteAnswer(session_->local_description());
   3079   SetRemoteDescriptionWithoutError(answer);
   3080 
   3081   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3082             session_->video_rtp_transport_channel());
   3083 }
   3084 
   3085 // kBundlePolicyBalanced BUNDLE policy but no BUNDLE in the answer.
   3086 TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
   3087   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
   3088   SendAudioVideoStream1();
   3089 
   3090   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3091   options.use_rtp_mux = true;
   3092 
   3093   SessionDescriptionInterface* offer = CreateOffer(options);
   3094   SetLocalDescriptionWithoutError(offer);
   3095 
   3096   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3097             session_->video_rtp_transport_channel());
   3098 
   3099   SendAudioVideoStream2();
   3100 
   3101   // Remove BUNDLE from the answer.
   3102   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3103       CreateRemoteAnswer(session_->local_description()));
   3104   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   3105   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   3106   JsepSessionDescription* modified_answer =
   3107       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   3108   modified_answer->Initialize(answer_copy, "1", "1");
   3109   SetRemoteDescriptionWithoutError(modified_answer);  //
   3110 
   3111   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3112             session_->video_rtp_transport_channel());
   3113 }
   3114 
   3115 // kBundlePolicyMaxBundle policy with BUNDLE in the answer.
   3116 TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
   3117   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3118   SendAudioVideoStream1();
   3119 
   3120   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3121   options.use_rtp_mux = true;
   3122 
   3123   SessionDescriptionInterface* offer = CreateOffer(options);
   3124   SetLocalDescriptionWithoutError(offer);
   3125 
   3126   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3127             session_->video_rtp_transport_channel());
   3128 
   3129   SendAudioVideoStream2();
   3130   SessionDescriptionInterface* answer =
   3131       CreateRemoteAnswer(session_->local_description());
   3132   SetRemoteDescriptionWithoutError(answer);
   3133 
   3134   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3135             session_->video_rtp_transport_channel());
   3136 }
   3137 
   3138 // kBundlePolicyMaxBundle policy with BUNDLE in the answer, but no
   3139 // audio content in the answer.
   3140 TEST_F(WebRtcSessionTest, TestMaxBundleRejectAudio) {
   3141   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3142   SendAudioVideoStream1();
   3143 
   3144   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3145   options.use_rtp_mux = true;
   3146 
   3147   SessionDescriptionInterface* offer = CreateOffer(options);
   3148   SetLocalDescriptionWithoutError(offer);
   3149 
   3150   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3151             session_->video_rtp_transport_channel());
   3152 
   3153   SendAudioVideoStream2();
   3154   cricket::MediaSessionOptions recv_options;
   3155   recv_options.recv_audio = false;
   3156   recv_options.recv_video = true;
   3157   SessionDescriptionInterface* answer =
   3158       CreateRemoteAnswer(session_->local_description(), recv_options);
   3159   SetRemoteDescriptionWithoutError(answer);
   3160 
   3161   EXPECT_TRUE(nullptr == session_->voice_channel());
   3162   EXPECT_TRUE(nullptr != session_->video_rtp_transport_channel());
   3163 
   3164   session_->Close();
   3165   EXPECT_TRUE(nullptr == session_->voice_rtp_transport_channel());
   3166   EXPECT_TRUE(nullptr == session_->voice_rtcp_transport_channel());
   3167   EXPECT_TRUE(nullptr == session_->video_rtp_transport_channel());
   3168   EXPECT_TRUE(nullptr == session_->video_rtcp_transport_channel());
   3169 }
   3170 
   3171 // kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
   3172 TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
   3173   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3174   SendAudioVideoStream1();
   3175 
   3176   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3177   options.use_rtp_mux = true;
   3178 
   3179   SessionDescriptionInterface* offer = CreateOffer(options);
   3180   SetLocalDescriptionWithoutError(offer);
   3181 
   3182   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3183             session_->video_rtp_transport_channel());
   3184 
   3185   SendAudioVideoStream2();
   3186 
   3187   // Remove BUNDLE from the answer.
   3188   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3189       CreateRemoteAnswer(session_->local_description()));
   3190   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   3191   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   3192   JsepSessionDescription* modified_answer =
   3193       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   3194   modified_answer->Initialize(answer_copy, "1", "1");
   3195   SetRemoteDescriptionWithoutError(modified_answer);
   3196 
   3197   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3198             session_->video_rtp_transport_channel());
   3199 }
   3200 
   3201 // kBundlePolicyMaxBundle policy with BUNDLE in the remote offer.
   3202 TEST_F(WebRtcSessionTest, TestMaxBundleBundleInRemoteOffer) {
   3203   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3204   SendAudioVideoStream1();
   3205 
   3206   SessionDescriptionInterface* offer = CreateRemoteOffer();
   3207   SetRemoteDescriptionWithoutError(offer);
   3208 
   3209   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3210             session_->video_rtp_transport_channel());
   3211 
   3212   SendAudioVideoStream2();
   3213   SessionDescriptionInterface* answer = CreateAnswer(nullptr);
   3214   SetLocalDescriptionWithoutError(answer);
   3215 
   3216   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3217             session_->video_rtp_transport_channel());
   3218 }
   3219 
   3220 // kBundlePolicyMaxBundle policy but no BUNDLE in the remote offer.
   3221 TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInRemoteOffer) {
   3222   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3223   SendAudioVideoStream1();
   3224 
   3225   // Remove BUNDLE from the offer.
   3226   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
   3227   cricket::SessionDescription* offer_copy = offer->description()->Copy();
   3228   offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   3229   JsepSessionDescription* modified_offer =
   3230       new JsepSessionDescription(JsepSessionDescription::kOffer);
   3231   modified_offer->Initialize(offer_copy, "1", "1");
   3232 
   3233   // Expect an error when applying the remote description
   3234   SetRemoteDescriptionExpectError(JsepSessionDescription::kOffer,
   3235                                   kCreateChannelFailed, modified_offer);
   3236 }
   3237 
   3238 // kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
   3239 TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
   3240   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
   3241   SendAudioVideoStream1();
   3242 
   3243   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3244   options.use_rtp_mux = true;
   3245 
   3246   SessionDescriptionInterface* offer = CreateOffer(options);
   3247   SetLocalDescriptionWithoutError(offer);
   3248 
   3249   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3250             session_->video_rtp_transport_channel());
   3251 
   3252   SendAudioVideoStream2();
   3253   SessionDescriptionInterface* answer =
   3254       CreateRemoteAnswer(session_->local_description());
   3255   SetRemoteDescriptionWithoutError(answer);
   3256 
   3257   // This should lead to an audio-only call but isn't implemented
   3258   // correctly yet.
   3259   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3260             session_->video_rtp_transport_channel());
   3261 }
   3262 
   3263 // kBundlePolicyMaxCompat BUNDLE policy but no BUNDLE in the answer.
   3264 TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
   3265   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
   3266   SendAudioVideoStream1();
   3267   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3268   options.use_rtp_mux = true;
   3269 
   3270   SessionDescriptionInterface* offer = CreateOffer(options);
   3271   SetLocalDescriptionWithoutError(offer);
   3272 
   3273   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3274             session_->video_rtp_transport_channel());
   3275 
   3276   SendAudioVideoStream2();
   3277 
   3278   // Remove BUNDLE from the answer.
   3279   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3280       CreateRemoteAnswer(session_->local_description()));
   3281   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   3282   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
   3283   JsepSessionDescription* modified_answer =
   3284       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   3285   modified_answer->Initialize(answer_copy, "1", "1");
   3286   SetRemoteDescriptionWithoutError(modified_answer);  //
   3287 
   3288   EXPECT_NE(session_->voice_rtp_transport_channel(),
   3289             session_->video_rtp_transport_channel());
   3290 }
   3291 
   3292 // kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
   3293 TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
   3294   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
   3295   SendAudioVideoStream1();
   3296 
   3297   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3298   options.use_rtp_mux = true;
   3299 
   3300   SessionDescriptionInterface* offer = CreateOffer(options);
   3301   SetRemoteDescriptionWithoutError(offer);
   3302 
   3303   EXPECT_EQ(session_->voice_rtp_transport_channel(),
   3304             session_->video_rtp_transport_channel());
   3305 }
   3306 
   3307 TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
   3308   InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
   3309   SendAudioVideoStream1();
   3310 
   3311   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3312   SessionDescriptionInterface* offer = CreateOffer(options);
   3313   SetLocalDescriptionWithoutError(offer);
   3314 
   3315   EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
   3316   EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
   3317 
   3318   SendAudioVideoStream2();
   3319   SessionDescriptionInterface* answer =
   3320       CreateRemoteAnswer(session_->local_description());
   3321   SetRemoteDescriptionWithoutError(answer);
   3322 
   3323   EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
   3324   EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
   3325 }
   3326 
   3327 TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
   3328   InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
   3329   SendAudioVideoStream1();
   3330 
   3331   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3332   SessionDescriptionInterface* offer = CreateOffer(options);
   3333   SetLocalDescriptionWithoutError(offer);
   3334 
   3335   EXPECT_TRUE(session_->voice_rtcp_transport_channel() != NULL);
   3336   EXPECT_TRUE(session_->video_rtcp_transport_channel() != NULL);
   3337 
   3338   SendAudioVideoStream2();
   3339   SessionDescriptionInterface* answer =
   3340       CreateRemoteAnswer(session_->local_description());
   3341   SetRemoteDescriptionWithoutError(answer);
   3342 
   3343   EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
   3344   EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
   3345 }
   3346 
   3347 // This test verifies that SetLocalDescription and SetRemoteDescription fails
   3348 // if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
   3349 TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
   3350   Init();
   3351   SendAudioVideoStream1();
   3352 
   3353   PeerConnectionInterface::RTCOfferAnswerOptions options;
   3354   options.use_rtp_mux = true;
   3355 
   3356   SessionDescriptionInterface* offer = CreateOffer(options);
   3357   std::string offer_str;
   3358   offer->ToString(&offer_str);
   3359   // Disable rtcp-mux
   3360   const std::string rtcp_mux = "rtcp-mux";
   3361   const std::string xrtcp_mux = "xrtcp-mux";
   3362   rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
   3363                              xrtcp_mux.c_str(), xrtcp_mux.length(),
   3364                              &offer_str);
   3365   JsepSessionDescription* local_offer =
   3366       new JsepSessionDescription(JsepSessionDescription::kOffer);
   3367   EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
   3368   SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
   3369   JsepSessionDescription* remote_offer =
   3370       new JsepSessionDescription(JsepSessionDescription::kOffer);
   3371   EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
   3372   SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
   3373   // Trying unmodified SDP.
   3374   SetLocalDescriptionWithoutError(offer);
   3375 }
   3376 
   3377 TEST_F(WebRtcSessionTest, SetAudioPlayout) {
   3378   Init();
   3379   SendAudioVideoStream1();
   3380   CreateAndSetRemoteOfferAndLocalAnswer();
   3381   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   3382   ASSERT_TRUE(channel != NULL);
   3383   ASSERT_EQ(1u, channel->recv_streams().size());
   3384   uint32_t receive_ssrc = channel->recv_streams()[0].first_ssrc();
   3385   double volume;
   3386   EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
   3387   EXPECT_EQ(1, volume);
   3388   session_->SetAudioPlayout(receive_ssrc, false);
   3389   EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
   3390   EXPECT_EQ(0, volume);
   3391   session_->SetAudioPlayout(receive_ssrc, true);
   3392   EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
   3393   EXPECT_EQ(1, volume);
   3394 }
   3395 
   3396 TEST_F(WebRtcSessionTest, SetAudioSend) {
   3397   Init();
   3398   SendAudioVideoStream1();
   3399   CreateAndSetRemoteOfferAndLocalAnswer();
   3400   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   3401   ASSERT_TRUE(channel != NULL);
   3402   ASSERT_EQ(1u, channel->send_streams().size());
   3403   uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
   3404   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   3405 
   3406   cricket::AudioOptions options;
   3407   options.echo_cancellation = rtc::Optional<bool>(true);
   3408 
   3409   rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   3410   session_->SetAudioSend(send_ssrc, false, options, renderer.get());
   3411   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
   3412   EXPECT_EQ(rtc::Optional<bool>(), channel->options().echo_cancellation);
   3413   EXPECT_TRUE(renderer->sink() != NULL);
   3414 
   3415   // This will trigger SetSink(NULL) to the |renderer|.
   3416   session_->SetAudioSend(send_ssrc, true, options, NULL);
   3417   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   3418   EXPECT_EQ(rtc::Optional<bool>(true), channel->options().echo_cancellation);
   3419   EXPECT_TRUE(renderer->sink() == NULL);
   3420 }
   3421 
   3422 TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
   3423   Init();
   3424   SendAudioVideoStream1();
   3425   CreateAndSetRemoteOfferAndLocalAnswer();
   3426   cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   3427   ASSERT_TRUE(channel != NULL);
   3428   ASSERT_EQ(1u, channel->send_streams().size());
   3429   uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
   3430 
   3431   rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   3432   cricket::AudioOptions options;
   3433   session_->SetAudioSend(send_ssrc, true, options, renderer.get());
   3434   EXPECT_TRUE(renderer->sink() != NULL);
   3435 
   3436   // Delete the |renderer| and it will trigger OnClose() to the sink, and this
   3437   // will invalidate the |renderer_| pointer in the sink and prevent getting a
   3438   // SetSink(NULL) callback afterwards.
   3439   renderer.reset();
   3440 
   3441   // This will trigger SetSink(NULL) if no OnClose() callback.
   3442   session_->SetAudioSend(send_ssrc, true, options, NULL);
   3443 }
   3444 
   3445 TEST_F(WebRtcSessionTest, SetVideoPlayout) {
   3446   Init();
   3447   SendAudioVideoStream1();
   3448   CreateAndSetRemoteOfferAndLocalAnswer();
   3449   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
   3450   ASSERT_TRUE(channel != NULL);
   3451   ASSERT_LT(0u, channel->renderers().size());
   3452   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
   3453   ASSERT_EQ(1u, channel->recv_streams().size());
   3454   uint32_t receive_ssrc = channel->recv_streams()[0].first_ssrc();
   3455   cricket::FakeVideoRenderer renderer;
   3456   session_->SetVideoPlayout(receive_ssrc, true, &renderer);
   3457   EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
   3458   session_->SetVideoPlayout(receive_ssrc, false, &renderer);
   3459   EXPECT_TRUE(channel->renderers().begin()->second == NULL);
   3460 }
   3461 
   3462 TEST_F(WebRtcSessionTest, SetVideoSend) {
   3463   Init();
   3464   SendAudioVideoStream1();
   3465   CreateAndSetRemoteOfferAndLocalAnswer();
   3466   cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
   3467   ASSERT_TRUE(channel != NULL);
   3468   ASSERT_EQ(1u, channel->send_streams().size());
   3469   uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
   3470   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   3471   cricket::VideoOptions* options = NULL;
   3472   session_->SetVideoSend(send_ssrc, false, options);
   3473   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
   3474   session_->SetVideoSend(send_ssrc, true, options);
   3475   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   3476 }
   3477 
   3478 TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
   3479   TestCanInsertDtmf(false);
   3480 }
   3481 
   3482 TEST_F(WebRtcSessionTest, CanInsertDtmf) {
   3483   TestCanInsertDtmf(true);
   3484 }
   3485 
   3486 TEST_F(WebRtcSessionTest, InsertDtmf) {
   3487   // Setup
   3488   Init();
   3489   SendAudioVideoStream1();
   3490   CreateAndSetRemoteOfferAndLocalAnswer();
   3491   FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
   3492   EXPECT_EQ(0U, channel->dtmf_info_queue().size());
   3493 
   3494   // Insert DTMF
   3495   const int expected_duration = 90;
   3496   session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
   3497   session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
   3498   session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
   3499 
   3500   // Verify
   3501   ASSERT_EQ(3U, channel->dtmf_info_queue().size());
   3502   const uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
   3503   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
   3504                               expected_duration));
   3505   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
   3506                               expected_duration));
   3507   EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
   3508                               expected_duration));
   3509 }
   3510 
   3511 // This test verifies the |initial_offerer| flag when session initiates the
   3512 // call.
   3513 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
   3514   Init();
   3515   EXPECT_FALSE(session_->initial_offerer());
   3516   SessionDescriptionInterface* offer = CreateOffer();
   3517   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   3518   SetLocalDescriptionWithoutError(offer);
   3519   EXPECT_TRUE(session_->initial_offerer());
   3520   SetRemoteDescriptionWithoutError(answer);
   3521   EXPECT_TRUE(session_->initial_offerer());
   3522 }
   3523 
   3524 // This test verifies the |initial_offerer| flag when session receives the call.
   3525 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
   3526   Init();
   3527   EXPECT_FALSE(session_->initial_offerer());
   3528   SessionDescriptionInterface* offer = CreateRemoteOffer();
   3529   SetRemoteDescriptionWithoutError(offer);
   3530   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   3531 
   3532   EXPECT_FALSE(session_->initial_offerer());
   3533   SetLocalDescriptionWithoutError(answer);
   3534   EXPECT_FALSE(session_->initial_offerer());
   3535 }
   3536 
   3537 // Verifing local offer and remote answer have matching m-lines as per RFC 3264.
   3538 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
   3539   Init();
   3540   SendAudioVideoStream1();
   3541   SessionDescriptionInterface* offer = CreateOffer();
   3542   SetLocalDescriptionWithoutError(offer);
   3543   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3544       CreateRemoteAnswer(session_->local_description()));
   3545 
   3546   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   3547   answer_copy->RemoveContentByName("video");
   3548   JsepSessionDescription* modified_answer =
   3549       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   3550 
   3551   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
   3552                                           answer->session_id(),
   3553                                           answer->session_version()));
   3554   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
   3555 
   3556   // Different content names.
   3557   std::string sdp;
   3558   EXPECT_TRUE(answer->ToString(&sdp));
   3559   const std::string kAudioMid = "a=mid:audio";
   3560   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
   3561   rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
   3562                              kAudioMidReplaceStr.c_str(),
   3563                              kAudioMidReplaceStr.length(),
   3564                              &sdp);
   3565   SessionDescriptionInterface* modified_answer1 =
   3566       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   3567   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
   3568 
   3569   // Different media types.
   3570   EXPECT_TRUE(answer->ToString(&sdp));
   3571   const std::string kAudioMline = "m=audio";
   3572   const std::string kAudioMlineReplaceStr = "m=video";
   3573   rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
   3574                              kAudioMlineReplaceStr.c_str(),
   3575                              kAudioMlineReplaceStr.length(),
   3576                              &sdp);
   3577   SessionDescriptionInterface* modified_answer2 =
   3578       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   3579   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
   3580 
   3581   SetRemoteDescriptionWithoutError(answer.release());
   3582 }
   3583 
   3584 // Verifying remote offer and local answer have matching m-lines as per
   3585 // RFC 3264.
   3586 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
   3587   Init();
   3588   SendAudioVideoStream1();
   3589   SessionDescriptionInterface* offer = CreateRemoteOffer();
   3590   SetRemoteDescriptionWithoutError(offer);
   3591   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   3592 
   3593   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   3594   answer_copy->RemoveContentByName("video");
   3595   JsepSessionDescription* modified_answer =
   3596       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   3597 
   3598   EXPECT_TRUE(modified_answer->Initialize(answer_copy,
   3599                                           answer->session_id(),
   3600                                           answer->session_version()));
   3601   SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
   3602   SetLocalDescriptionWithoutError(answer);
   3603 }
   3604 
   3605 // This test verifies that WebRtcSession does not start candidate allocation
   3606 // before SetLocalDescription is called.
   3607 TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
   3608   Init();
   3609   SendAudioVideoStream1();
   3610   SessionDescriptionInterface* offer = CreateRemoteOffer();
   3611   cricket::Candidate candidate;
   3612   candidate.set_component(1);
   3613   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
   3614                                  candidate);
   3615   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   3616   cricket::Candidate candidate1;
   3617   candidate1.set_component(1);
   3618   JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
   3619                                   candidate1);
   3620   EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
   3621   SetRemoteDescriptionWithoutError(offer);
   3622   ASSERT_TRUE(session_->voice_rtp_transport_channel() != NULL);
   3623   ASSERT_TRUE(session_->video_rtp_transport_channel() != NULL);
   3624 
   3625   // Pump for 1 second and verify that no candidates are generated.
   3626   rtc::Thread::Current()->ProcessMessages(1000);
   3627   EXPECT_TRUE(observer_.mline_0_candidates_.empty());
   3628   EXPECT_TRUE(observer_.mline_1_candidates_.empty());
   3629 
   3630   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   3631   SetLocalDescriptionWithoutError(answer);
   3632   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
   3633 }
   3634 
   3635 // This test verifies that crypto parameter is updated in local session
   3636 // description as per security policy set in MediaSessionDescriptionFactory.
   3637 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
   3638   Init();
   3639   SendAudioVideoStream1();
   3640   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   3641 
   3642   // Making sure SetLocalDescription correctly sets crypto value in
   3643   // SessionDescription object after de-serialization of sdp string. The value
   3644   // will be set as per MediaSessionDescriptionFactory.
   3645   std::string offer_str;
   3646   offer->ToString(&offer_str);
   3647   SessionDescriptionInterface* jsep_offer_str =
   3648       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
   3649   SetLocalDescriptionWithoutError(jsep_offer_str);
   3650   EXPECT_TRUE(session_->voice_channel()->secure_required());
   3651   EXPECT_TRUE(session_->video_channel()->secure_required());
   3652 }
   3653 
   3654 // This test verifies the crypto parameter when security is disabled.
   3655 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
   3656   options_.disable_encryption = true;
   3657   Init();
   3658   SendAudioVideoStream1();
   3659   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   3660 
   3661   // Making sure SetLocalDescription correctly sets crypto value in
   3662   // SessionDescription object after de-serialization of sdp string. The value
   3663   // will be set as per MediaSessionDescriptionFactory.
   3664   std::string offer_str;
   3665   offer->ToString(&offer_str);
   3666   SessionDescriptionInterface* jsep_offer_str =
   3667       CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
   3668   SetLocalDescriptionWithoutError(jsep_offer_str);
   3669   EXPECT_FALSE(session_->voice_channel()->secure_required());
   3670   EXPECT_FALSE(session_->video_channel()->secure_required());
   3671 }
   3672 
   3673 // This test verifies that an answer contains new ufrag and password if an offer
   3674 // with new ufrag and password is received.
   3675 TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
   3676   Init();
   3677   cricket::MediaSessionOptions options;
   3678   options.recv_video = true;
   3679   rtc::scoped_ptr<JsepSessionDescription> offer(
   3680       CreateRemoteOffer(options));
   3681   SetRemoteDescriptionWithoutError(offer.release());
   3682 
   3683   SendAudioVideoStream1();
   3684   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3685       CreateAnswer(NULL));
   3686   SetLocalDescriptionWithoutError(answer.release());
   3687 
   3688   // Receive an offer with new ufrag and password.
   3689   options.audio_transport_options.ice_restart = true;
   3690   options.video_transport_options.ice_restart = true;
   3691   options.data_transport_options.ice_restart = true;
   3692   rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
   3693       CreateRemoteOffer(options, session_->remote_description()));
   3694   SetRemoteDescriptionWithoutError(updated_offer1.release());
   3695 
   3696   rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
   3697       CreateAnswer(NULL));
   3698 
   3699   CompareIceUfragAndPassword(updated_answer1->description(),
   3700                              session_->local_description()->description(),
   3701                              false);
   3702 
   3703   SetLocalDescriptionWithoutError(updated_answer1.release());
   3704 }
   3705 
   3706 // This test verifies that an answer contains old ufrag and password if an offer
   3707 // with old ufrag and password is received.
   3708 TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
   3709   Init();
   3710   cricket::MediaSessionOptions options;
   3711   options.recv_video = true;
   3712   rtc::scoped_ptr<JsepSessionDescription> offer(
   3713       CreateRemoteOffer(options));
   3714   SetRemoteDescriptionWithoutError(offer.release());
   3715 
   3716   SendAudioVideoStream1();
   3717   rtc::scoped_ptr<SessionDescriptionInterface> answer(
   3718       CreateAnswer(NULL));
   3719   SetLocalDescriptionWithoutError(answer.release());
   3720 
   3721   // Receive an offer without changed ufrag or password.
   3722   options.audio_transport_options.ice_restart = false;
   3723   options.video_transport_options.ice_restart = false;
   3724   options.data_transport_options.ice_restart = false;
   3725   rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
   3726       CreateRemoteOffer(options, session_->remote_description()));
   3727   SetRemoteDescriptionWithoutError(updated_offer2.release());
   3728 
   3729   rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
   3730       CreateAnswer(NULL));
   3731 
   3732   CompareIceUfragAndPassword(updated_answer2->description(),
   3733                              session_->local_description()->description(),
   3734                              true);
   3735 
   3736   SetLocalDescriptionWithoutError(updated_answer2.release());
   3737 }
   3738 
   3739 TEST_F(WebRtcSessionTest, TestSessionContentError) {
   3740   Init();
   3741   SendAudioVideoStream1();
   3742   SessionDescriptionInterface* offer = CreateOffer();
   3743   const std::string session_id_orig = offer->session_id();
   3744   const std::string session_version_orig = offer->session_version();
   3745   SetLocalDescriptionWithoutError(offer);
   3746 
   3747   video_channel_ = media_engine_->GetVideoChannel(0);
   3748   video_channel_->set_fail_set_send_codecs(true);
   3749 
   3750   SessionDescriptionInterface* answer =
   3751       CreateRemoteAnswer(session_->local_description());
   3752   SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
   3753 
   3754   // Test that after a content error, setting any description will
   3755   // result in an error.
   3756   video_channel_->set_fail_set_send_codecs(false);
   3757   answer = CreateRemoteAnswer(session_->local_description());
   3758   SetRemoteDescriptionExpectError("", "ERROR_CONTENT", answer);
   3759   offer = CreateRemoteOffer();
   3760   SetLocalDescriptionExpectError("", "ERROR_CONTENT", offer);
   3761 }
   3762 
   3763 // Runs the loopback call test with BUNDLE and STUN disabled.
   3764 TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
   3765   // Lets try with only UDP ports.
   3766   allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
   3767                         cricket::PORTALLOCATOR_DISABLE_STUN |
   3768                         cricket::PORTALLOCATOR_DISABLE_RELAY);
   3769   TestLoopbackCall();
   3770 }
   3771 
   3772 TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
   3773   allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
   3774                         cricket::PORTALLOCATOR_DISABLE_STUN |
   3775                         cricket::PORTALLOCATOR_ENABLE_IPV6 |
   3776                         cricket::PORTALLOCATOR_DISABLE_RELAY);
   3777 
   3778   // best connection is IPv6 since it has higher network preference.
   3779   LoopbackNetworkConfiguration config;
   3780   config.test_ipv6_network_ = true;
   3781   config.best_connection_after_initial_ice_converged_ =
   3782       LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
   3783 
   3784   TestLoopbackCall(config);
   3785 }
   3786 
   3787 // Runs the loopback call test with BUNDLE and STUN enabled.
   3788 TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
   3789   allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
   3790                         cricket::PORTALLOCATOR_DISABLE_RELAY);
   3791   TestLoopbackCall();
   3792 }
   3793 
   3794 TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
   3795   constraints_.reset(new FakeConstraints());
   3796   constraints_->AddOptional(
   3797       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
   3798   Init();
   3799 
   3800   SetLocalDescriptionWithDataChannel();
   3801   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
   3802 }
   3803 
   3804 TEST_P(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
   3805   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3806 
   3807   constraints_.reset(new FakeConstraints());
   3808   constraints_->AddOptional(
   3809       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
   3810   options_.disable_sctp_data_channels = false;
   3811 
   3812   InitWithDtls(GetParam());
   3813 
   3814   SetLocalDescriptionWithDataChannel();
   3815   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
   3816 }
   3817 
   3818 TEST_P(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
   3819   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3820 
   3821   InitWithDtls(GetParam());
   3822 
   3823   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   3824   EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
   3825   EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
   3826 }
   3827 
   3828 TEST_P(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
   3829   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3830   SetFactoryDtlsSrtp();
   3831   InitWithDtls(GetParam());
   3832 
   3833   // Create remote offer with SCTP.
   3834   cricket::MediaSessionOptions options;
   3835   options.data_channel_type = cricket::DCT_SCTP;
   3836   JsepSessionDescription* offer =
   3837       CreateRemoteOffer(options, cricket::SEC_DISABLED);
   3838   SetRemoteDescriptionWithoutError(offer);
   3839 
   3840   // Verifies the answer contains SCTP.
   3841   rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   3842   EXPECT_TRUE(answer != NULL);
   3843   EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
   3844   EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
   3845 }
   3846 
   3847 TEST_P(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
   3848   constraints_.reset(new FakeConstraints());
   3849   constraints_->AddOptional(
   3850       webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
   3851   InitWithDtls(GetParam());
   3852 
   3853   SetLocalDescriptionWithDataChannel();
   3854   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
   3855 }
   3856 
   3857 TEST_P(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
   3858   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3859 
   3860   InitWithDtls(GetParam());
   3861 
   3862   SetLocalDescriptionWithDataChannel();
   3863   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
   3864 }
   3865 
   3866 TEST_P(WebRtcSessionTest, TestDisableSctpDataChannels) {
   3867   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3868   options_.disable_sctp_data_channels = true;
   3869   InitWithDtls(GetParam());
   3870 
   3871   SetLocalDescriptionWithDataChannel();
   3872   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
   3873 }
   3874 
   3875 TEST_P(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
   3876   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3877   const int new_send_port = 9998;
   3878   const int new_recv_port = 7775;
   3879 
   3880   InitWithDtls(GetParam());
   3881   SetFactoryDtlsSrtp();
   3882 
   3883   // By default, don't actually add the codecs to desc_factory_; they don't
   3884   // actually get serialized for SCTP in BuildMediaDescription().  Instead,
   3885   // let the session description get parsed.  That'll get the proper codecs
   3886   // into the stream.
   3887   cricket::MediaSessionOptions options;
   3888   JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
   3889       "stream1", new_send_port, options);
   3890 
   3891   // SetRemoteDescription will take the ownership of the offer.
   3892   SetRemoteDescriptionWithoutError(offer);
   3893 
   3894   SessionDescriptionInterface* answer = ChangeSDPSctpPort(
   3895       new_recv_port, CreateAnswer(NULL));
   3896   ASSERT_TRUE(answer != NULL);
   3897 
   3898   // Now set the local description, which'll take ownership of the answer.
   3899   SetLocalDescriptionWithoutError(answer);
   3900 
   3901   // TEST PLAN: Set the port number to something new, set it in the SDP,
   3902   // and pass it all the way down.
   3903   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
   3904   CreateDataChannel();
   3905 
   3906   cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
   3907   int portnum = -1;
   3908   ASSERT_TRUE(ch != NULL);
   3909   ASSERT_EQ(1UL, ch->send_codecs().size());
   3910   EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
   3911   EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
   3912                       ch->send_codecs()[0].name.c_str()));
   3913   EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
   3914                                             &portnum));
   3915   EXPECT_EQ(new_send_port, portnum);
   3916 
   3917   ASSERT_EQ(1UL, ch->recv_codecs().size());
   3918   EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
   3919   EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
   3920                       ch->recv_codecs()[0].name.c_str()));
   3921   EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
   3922                                             &portnum));
   3923   EXPECT_EQ(new_recv_port, portnum);
   3924 }
   3925 
   3926 // Verifies that when a session's DataChannel receives an OPEN message,
   3927 // WebRtcSession signals the DataChannel creation request with the expected
   3928 // config.
   3929 TEST_P(WebRtcSessionTest, TestSctpDataChannelOpenMessage) {
   3930   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3931 
   3932   InitWithDtls(GetParam());
   3933 
   3934   SetLocalDescriptionWithDataChannel();
   3935   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
   3936 
   3937   webrtc::DataChannelInit config;
   3938   config.id = 1;
   3939   rtc::Buffer payload;
   3940   webrtc::WriteDataChannelOpenMessage("a", config, &payload);
   3941   cricket::ReceiveDataParams params;
   3942   params.ssrc = config.id;
   3943   params.type = cricket::DMT_CONTROL;
   3944 
   3945   cricket::DataChannel* data_channel = session_->data_channel();
   3946   data_channel->SignalDataReceived(data_channel, params, payload);
   3947 
   3948   EXPECT_EQ("a", last_data_channel_label_);
   3949   EXPECT_EQ(config.id, last_data_channel_config_.id);
   3950   EXPECT_FALSE(last_data_channel_config_.negotiated);
   3951   EXPECT_EQ(webrtc::InternalDataChannelInit::kAcker,
   3952             last_data_channel_config_.open_handshake_role);
   3953 }
   3954 
   3955 TEST_P(WebRtcSessionTest, TestUsesProvidedCertificate) {
   3956   rtc::scoped_refptr<rtc::RTCCertificate> certificate =
   3957       FakeDtlsIdentityStore::GenerateCertificate();
   3958 
   3959   PeerConnectionInterface::RTCConfiguration configuration;
   3960   configuration.certificates.push_back(certificate);
   3961   Init(nullptr, configuration);
   3962   EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
   3963 
   3964   EXPECT_EQ(session_->certificate_for_testing(), certificate);
   3965 }
   3966 
   3967 // Verifies that CreateOffer succeeds when CreateOffer is called before async
   3968 // identity generation is finished (even if a certificate is provided this is
   3969 // an async op).
   3970 TEST_P(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
   3971   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3972   InitWithDtls(GetParam());
   3973 
   3974   EXPECT_TRUE(session_->waiting_for_certificate_for_testing());
   3975   SendAudioVideoStream1();
   3976   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   3977 
   3978   EXPECT_TRUE(offer != NULL);
   3979   VerifyNoCryptoParams(offer->description(), true);
   3980   VerifyFingerprintStatus(offer->description(), true);
   3981 }
   3982 
   3983 // Verifies that CreateAnswer succeeds when CreateOffer is called before async
   3984 // identity generation is finished (even if a certificate is provided this is
   3985 // an async op).
   3986 TEST_P(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
   3987   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   3988   InitWithDtls(GetParam());
   3989   SetFactoryDtlsSrtp();
   3990 
   3991   cricket::MediaSessionOptions options;
   3992   options.recv_video = true;
   3993   scoped_ptr<JsepSessionDescription> offer(
   3994         CreateRemoteOffer(options, cricket::SEC_DISABLED));
   3995   ASSERT_TRUE(offer.get() != NULL);
   3996   SetRemoteDescriptionWithoutError(offer.release());
   3997 
   3998   rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   3999   EXPECT_TRUE(answer != NULL);
   4000   VerifyNoCryptoParams(answer->description(), true);
   4001   VerifyFingerprintStatus(answer->description(), true);
   4002 }
   4003 
   4004 // Verifies that CreateOffer succeeds when CreateOffer is called after async
   4005 // identity generation is finished (even if a certificate is provided this is
   4006 // an async op).
   4007 TEST_P(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
   4008   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4009   InitWithDtls(GetParam());
   4010 
   4011   EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
   4012 
   4013   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   4014   EXPECT_TRUE(offer != NULL);
   4015 }
   4016 
   4017 // Verifies that CreateOffer fails when CreateOffer is called after async
   4018 // identity generation fails.
   4019 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
   4020   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4021   InitWithDtlsIdentityGenFail();
   4022 
   4023   EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
   4024 
   4025   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   4026   EXPECT_TRUE(offer == NULL);
   4027 }
   4028 
   4029 // Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
   4030 // before async identity generation is finished.
   4031 TEST_P(WebRtcSessionTest,
   4032        TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
   4033   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4034   VerifyMultipleAsyncCreateDescription(GetParam(),
   4035                                        CreateSessionDescriptionRequest::kOffer);
   4036 }
   4037 
   4038 // Verifies that CreateOffer fails when Multiple CreateOffer calls are made
   4039 // before async identity generation fails.
   4040 TEST_F(WebRtcSessionTest,
   4041        TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
   4042   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4043   VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
   4044       CreateSessionDescriptionRequest::kOffer);
   4045 }
   4046 
   4047 // Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
   4048 // before async identity generation is finished.
   4049 TEST_P(WebRtcSessionTest,
   4050        TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
   4051   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4052   VerifyMultipleAsyncCreateDescription(
   4053       GetParam(), CreateSessionDescriptionRequest::kAnswer);
   4054 }
   4055 
   4056 // Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
   4057 // before async identity generation fails.
   4058 TEST_F(WebRtcSessionTest,
   4059        TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
   4060   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4061   VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
   4062       CreateSessionDescriptionRequest::kAnswer);
   4063 }
   4064 
   4065 // Verifies that setRemoteDescription fails when DTLS is disabled and the remote
   4066 // offer has no SDES crypto but only DTLS fingerprint.
   4067 TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
   4068   // Init without DTLS.
   4069   Init();
   4070   // Create a remote offer with secured transport disabled.
   4071   cricket::MediaSessionOptions options;
   4072   JsepSessionDescription* offer(CreateRemoteOffer(
   4073       options, cricket::SEC_DISABLED));
   4074   // Adds a DTLS fingerprint to the remote offer.
   4075   cricket::SessionDescription* sdp = offer->description();
   4076   TransportInfo* audio = sdp->GetTransportInfoByName("audio");
   4077   ASSERT_TRUE(audio != NULL);
   4078   ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
   4079   audio->description.identity_fingerprint.reset(
   4080       rtc::SSLFingerprint::CreateFromRfc4572(
   4081           rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
   4082   SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
   4083                                        offer);
   4084 }
   4085 
   4086 // This test verifies DSCP is properly applied on the media channels.
   4087 TEST_F(WebRtcSessionTest, TestDscpConstraint) {
   4088   constraints_.reset(new FakeConstraints());
   4089   constraints_->AddOptional(
   4090       webrtc::MediaConstraintsInterface::kEnableDscp, true);
   4091   Init();
   4092   SendAudioVideoStream1();
   4093   SessionDescriptionInterface* offer = CreateOffer();
   4094 
   4095   SetLocalDescriptionWithoutError(offer);
   4096 
   4097   video_channel_ = media_engine_->GetVideoChannel(0);
   4098   voice_channel_ = media_engine_->GetVoiceChannel(0);
   4099 
   4100   ASSERT_TRUE(video_channel_ != NULL);
   4101   ASSERT_TRUE(voice_channel_ != NULL);
   4102   const cricket::AudioOptions& audio_options = voice_channel_->options();
   4103   const cricket::VideoOptions& video_options = video_channel_->options();
   4104   EXPECT_EQ(rtc::Optional<bool>(true), audio_options.dscp);
   4105   EXPECT_EQ(rtc::Optional<bool>(true), video_options.dscp);
   4106 }
   4107 
   4108 TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
   4109   constraints_.reset(new FakeConstraints());
   4110   constraints_->AddOptional(
   4111       webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
   4112       true);
   4113   Init();
   4114   SendAudioVideoStream1();
   4115   SessionDescriptionInterface* offer = CreateOffer();
   4116 
   4117   SetLocalDescriptionWithoutError(offer);
   4118 
   4119   video_channel_ = media_engine_->GetVideoChannel(0);
   4120 
   4121   ASSERT_TRUE(video_channel_ != NULL);
   4122   const cricket::VideoOptions& video_options = video_channel_->options();
   4123   EXPECT_EQ(rtc::Optional<bool>(true), video_options.suspend_below_min_bitrate);
   4124 }
   4125 
   4126 TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
   4127   // Number of unsignalled receiving streams should be between 0 and
   4128   // kMaxUnsignalledRecvStreams.
   4129   SetAndVerifyNumUnsignalledRecvStreams(10, 10);
   4130   SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
   4131                                         kMaxUnsignalledRecvStreams);
   4132   SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
   4133 }
   4134 
   4135 TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
   4136   constraints_.reset(new FakeConstraints());
   4137   constraints_->AddOptional(
   4138       webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
   4139       true);
   4140   Init();
   4141   SendAudioVideoStream1();
   4142   SessionDescriptionInterface* offer = CreateOffer();
   4143 
   4144   SetLocalDescriptionWithoutError(offer);
   4145 
   4146   voice_channel_ = media_engine_->GetVoiceChannel(0);
   4147 
   4148   ASSERT_TRUE(voice_channel_ != NULL);
   4149   const cricket::AudioOptions& audio_options = voice_channel_->options();
   4150   EXPECT_EQ(rtc::Optional<bool>(true), audio_options.combined_audio_video_bwe);
   4151 }
   4152 
   4153 // Tests that we can renegotiate new media content with ICE candidates in the
   4154 // new remote SDP.
   4155 TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
   4156   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4157   InitWithDtls(GetParam());
   4158   SetFactoryDtlsSrtp();
   4159 
   4160   SendAudioOnlyStream2();
   4161   SessionDescriptionInterface* offer = CreateOffer();
   4162   SetLocalDescriptionWithoutError(offer);
   4163 
   4164   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   4165   SetRemoteDescriptionWithoutError(answer);
   4166 
   4167   cricket::MediaSessionOptions options;
   4168   options.recv_video = true;
   4169   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
   4170 
   4171   cricket::Candidate candidate1;
   4172   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
   4173   candidate1.set_component(1);
   4174   JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
   4175                                  candidate1);
   4176   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   4177   SetRemoteDescriptionWithoutError(offer);
   4178 
   4179   answer = CreateAnswer(NULL);
   4180   SetLocalDescriptionWithoutError(answer);
   4181 }
   4182 
   4183 // Tests that we can renegotiate new media content with ICE candidates separated
   4184 // from the remote SDP.
   4185 TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
   4186   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   4187   InitWithDtls(GetParam());
   4188   SetFactoryDtlsSrtp();
   4189 
   4190   SendAudioOnlyStream2();
   4191   SessionDescriptionInterface* offer = CreateOffer();
   4192   SetLocalDescriptionWithoutError(offer);
   4193 
   4194   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   4195   SetRemoteDescriptionWithoutError(answer);
   4196 
   4197   cricket::MediaSessionOptions options;
   4198   options.recv_video = true;
   4199   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
   4200   SetRemoteDescriptionWithoutError(offer);
   4201 
   4202   cricket::Candidate candidate1;
   4203   candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
   4204   candidate1.set_component(1);
   4205   JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
   4206                                  candidate1);
   4207   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
   4208 
   4209   answer = CreateAnswer(NULL);
   4210   SetLocalDescriptionWithoutError(answer);
   4211 }
   4212 // Tests that RTX codec is removed from the answer when it isn't supported
   4213 // by local side.
   4214 TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
   4215   Init();
   4216   SendAudioVideoStream1();
   4217   std::string offer_sdp(kSdpWithRtx);
   4218 
   4219   SessionDescriptionInterface* offer =
   4220       CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
   4221   EXPECT_TRUE(offer->ToString(&offer_sdp));
   4222 
   4223   // Offer SDP contains the RTX codec.
   4224   EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
   4225   SetRemoteDescriptionWithoutError(offer);
   4226 
   4227   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   4228   std::string answer_sdp;
   4229   answer->ToString(&answer_sdp);
   4230   // Answer SDP removes the unsupported RTX codec.
   4231   EXPECT_TRUE(answer_sdp.find("rtx") == std::string::npos);
   4232   SetLocalDescriptionWithoutError(answer);
   4233 }
   4234 
   4235 // This verifies that the voice channel after bundle has both options from video
   4236 // and voice channels.
   4237 TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
   4238   InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
   4239   SendAudioVideoStream1();
   4240 
   4241   PeerConnectionInterface::RTCOfferAnswerOptions options;
   4242   options.use_rtp_mux = true;
   4243 
   4244   SessionDescriptionInterface* offer = CreateOffer(options);
   4245   SetLocalDescriptionWithoutError(offer);
   4246 
   4247   session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
   4248                                        rtc::Socket::Option::OPT_SNDBUF, 4000);
   4249 
   4250   session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
   4251                                        rtc::Socket::Option::OPT_RCVBUF, 8000);
   4252 
   4253   int option_val;
   4254   EXPECT_TRUE(session_->video_rtp_transport_channel()->GetOption(
   4255       rtc::Socket::Option::OPT_SNDBUF, &option_val));
   4256   EXPECT_EQ(4000, option_val);
   4257   EXPECT_FALSE(session_->voice_rtp_transport_channel()->GetOption(
   4258       rtc::Socket::Option::OPT_SNDBUF, &option_val));
   4259 
   4260   EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
   4261       rtc::Socket::Option::OPT_RCVBUF, &option_val));
   4262   EXPECT_EQ(8000, option_val);
   4263   EXPECT_FALSE(session_->video_rtp_transport_channel()->GetOption(
   4264       rtc::Socket::Option::OPT_RCVBUF, &option_val));
   4265 
   4266   EXPECT_NE(session_->voice_rtp_transport_channel(),
   4267             session_->video_rtp_transport_channel());
   4268 
   4269   SendAudioVideoStream2();
   4270   SessionDescriptionInterface* answer =
   4271       CreateRemoteAnswer(session_->local_description());
   4272   SetRemoteDescriptionWithoutError(answer);
   4273 
   4274   EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
   4275       rtc::Socket::Option::OPT_SNDBUF, &option_val));
   4276   EXPECT_EQ(4000, option_val);
   4277 
   4278   EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
   4279       rtc::Socket::Option::OPT_RCVBUF, &option_val));
   4280   EXPECT_EQ(8000, option_val);
   4281 }
   4282 
   4283 // Test creating a session, request multiple offers, destroy the session
   4284 // and make sure we got success/failure callbacks for all of the requests.
   4285 // Background: crbug.com/507307
   4286 TEST_F(WebRtcSessionTest, CreateOffersAndShutdown) {
   4287   Init();
   4288 
   4289   rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observers[100];
   4290   PeerConnectionInterface::RTCOfferAnswerOptions options;
   4291   options.offer_to_receive_audio =
   4292       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
   4293   cricket::MediaSessionOptions session_options;
   4294   session_options.recv_audio = true;
   4295 
   4296   for (auto& o : observers) {
   4297     o = new WebRtcSessionCreateSDPObserverForTest();
   4298     session_->CreateOffer(o, options, session_options);
   4299   }
   4300 
   4301   session_.reset();
   4302 
   4303   for (auto& o : observers) {
   4304     // We expect to have received a notification now even if the session was
   4305     // terminated.  The offer creation may or may not have succeeded, but we
   4306     // must have received a notification which, so the only invalid state
   4307     // is kInit.
   4308     EXPECT_NE(WebRtcSessionCreateSDPObserverForTest::kInit, o->state());
   4309   }
   4310 }
   4311 
   4312 TEST_F(WebRtcSessionTest, TestPacketOptionsAndOnPacketSent) {
   4313   TestPacketOptions();
   4314 }
   4315 
   4316 // TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled.  That test
   4317 // currently fails because upon disconnection and reconnection OnIceComplete is
   4318 // called more than once without returning to IceGatheringGathering.
   4319 
   4320 INSTANTIATE_TEST_CASE_P(WebRtcSessionTests,
   4321                         WebRtcSessionTest,
   4322                         testing::Values(ALREADY_GENERATED,
   4323                                         DTLS_IDENTITY_STORE));
   4324