Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / app / webrtc / webrtcsession_unittest.cc
index d9ce644..206f320 100644 (file)
 #include "talk/app/webrtc/jsepsessiondescription.h"
 #include "talk/app/webrtc/mediastreamsignaling.h"
 #include "talk/app/webrtc/streamcollection.h"
-#include "talk/app/webrtc/videotrack.h"
 #include "talk/app/webrtc/test/fakeconstraints.h"
 #include "talk/app/webrtc/test/fakedtlsidentityservice.h"
 #include "talk/app/webrtc/test/fakemediastreamsignaling.h"
+#include "talk/app/webrtc/videotrack.h"
 #include "talk/app/webrtc/webrtcsession.h"
 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
-#include "talk/base/fakenetwork.h"
-#include "talk/base/firewallsocketserver.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/network.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/ssladapter.h"
-#include "talk/base/sslstreamadapter.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/base/virtualsocketserver.h"
 #include "talk/media/base/fakemediaengine.h"
 #include "talk/media/base/fakevideorenderer.h"
 #include "talk/media/base/mediachannel.h"
 #include "talk/media/devices/fakedevicemanager.h"
 #include "talk/p2p/base/stunserver.h"
 #include "talk/p2p/base/teststunserver.h"
+#include "talk/p2p/base/testturnserver.h"
 #include "talk/p2p/client/basicportallocator.h"
 #include "talk/session/media/channelmanager.h"
 #include "talk/session/media/mediasession.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/firewallsocketserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/network.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/sslstreamadapter.h"
+#include "webrtc/base/stringutils.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
 
 #define MAYBE_SKIP_TEST(feature)                    \
   if (!(feature())) {                               \
@@ -70,8 +71,9 @@ using cricket::FakeVoiceMediaChannel;
 using cricket::NS_GINGLE_P2P;
 using cricket::NS_JINGLE_ICE_UDP;
 using cricket::TransportInfo;
-using talk_base::SocketAddress;
-using talk_base::scoped_ptr;
+using rtc::SocketAddress;
+using rtc::scoped_ptr;
+using rtc::Thread;
 using webrtc::CreateSessionDescription;
 using webrtc::CreateSessionDescriptionObserver;
 using webrtc::CreateSessionDescriptionRequest;
@@ -91,16 +93,21 @@ using webrtc::kCreateChannelFailed;
 using webrtc::kInvalidSdp;
 using webrtc::kMlineMismatch;
 using webrtc::kPushDownTDFailed;
-using webrtc::kSdpWithoutCrypto;
 using webrtc::kSdpWithoutIceUfragPwd;
-using webrtc::kSdpWithoutSdesAndDtlsDisabled;
+using webrtc::kSdpWithoutDtlsFingerprint;
+using webrtc::kSdpWithoutSdesCrypto;
 using webrtc::kSessionError;
 using webrtc::kSessionErrorDesc;
+using webrtc::kMaxUnsignalledRecvStreams;
+
+typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
 
 static const int kClientAddrPort = 0;
 static const char kClientAddrHost1[] = "11.11.11.11";
 static const char kClientAddrHost2[] = "22.22.22.22";
 static const char kStunAddrHost[] = "99.99.99.1";
+static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
+static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
 
 static const char kSessionVersion[] = "1";
 
@@ -118,12 +125,18 @@ static const char kFakeDtlsFingerprint[] =
     "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
     "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
 
+static const char kTooLongIceUfragPwd[] =
+    "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
+    "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
+    "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
+    "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
+
 // Add some extra |newlines| to the |message| after |line|.
 static void InjectAfter(const std::string& line,
                         const std::string& newlines,
                         std::string* message) {
   const std::string tmp = line + newlines;
-  talk_base::replace_substrs(line.c_str(), line.length(),
+  rtc::replace_substrs(line.c_str(), line.length(),
                              tmp.c_str(), tmp.length(), message);
 }
 
@@ -193,8 +206,8 @@ class MockIceObserver : public webrtc::IceObserver {
 class WebRtcSessionForTest : public webrtc::WebRtcSession {
  public:
   WebRtcSessionForTest(cricket::ChannelManager* cmgr,
-                       talk_base::Thread* signaling_thread,
-                       talk_base::Thread* worker_thread,
+                       rtc::Thread* signaling_thread,
+                       rtc::Thread* worker_thread,
                        cricket::PortAllocator* port_allocator,
                        webrtc::IceObserver* ice_observer,
                        webrtc::MediaStreamSignaling* mediastream_signaling)
@@ -213,7 +226,7 @@ class WebRtcSessionForTest : public webrtc::WebRtcSession {
 };
 
 class WebRtcSessionCreateSDPObserverForTest
-    : public talk_base::RefCountedObject<CreateSessionDescriptionObserver> {
+    : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
  public:
   enum State {
     kInit,
@@ -243,13 +256,17 @@ class WebRtcSessionCreateSDPObserverForTest
   ~WebRtcSessionCreateSDPObserverForTest() {}
 
  private:
-  talk_base::scoped_ptr<SessionDescriptionInterface> description_;
+  rtc::scoped_ptr<SessionDescriptionInterface> description_;
   State state_;
 };
 
 class FakeAudioRenderer : public cricket::AudioRenderer {
  public:
-  FakeAudioRenderer() : channel_id_(-1) {}
+  FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
+  virtual ~FakeAudioRenderer() {
+    if (sink_)
+      sink_->OnClose();
+  }
 
   virtual void AddChannel(int channel_id) OVERRIDE {
     ASSERT(channel_id_ == -1);
@@ -259,10 +276,15 @@ class FakeAudioRenderer : public cricket::AudioRenderer {
     ASSERT(channel_id == channel_id_);
     channel_id_ = -1;
   }
+  virtual void SetSink(Sink* sink) OVERRIDE {
+    sink_ = sink;
+  }
 
   int channel_id() const { return channel_id_; }
+  cricket::AudioRenderer::Sink* sink() const { return sink_; }
  private:
   int channel_id_;
+  cricket::AudioRenderer::Sink* sink_;
 };
 
 class WebRtcSessionTest : public testing::Test {
@@ -275,45 +297,57 @@ class WebRtcSessionTest : public testing::Test {
       device_manager_(new cricket::FakeDeviceManager()),
       channel_manager_(new cricket::ChannelManager(
          media_engine_, data_engine_, device_manager_,
-         new cricket::CaptureManager(), talk_base::Thread::Current())),
+         new cricket::CaptureManager(), rtc::Thread::Current())),
       tdesc_factory_(new cricket::TransportDescriptionFactory()),
       desc_factory_(new cricket::MediaSessionDescriptionFactory(
           channel_manager_.get(), tdesc_factory_.get())),
-      pss_(new talk_base::PhysicalSocketServer),
-      vss_(new talk_base::VirtualSocketServer(pss_.get())),
-      fss_(new talk_base::FirewallSocketServer(vss_.get())),
+      pss_(new rtc::PhysicalSocketServer),
+      vss_(new rtc::VirtualSocketServer(pss_.get())),
+      fss_(new rtc::FirewallSocketServer(vss_.get())),
       ss_scope_(fss_.get()),
-      stun_socket_addr_(talk_base::SocketAddress(kStunAddrHost,
+      stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
                                                  cricket::STUN_SERVER_PORT)),
-      stun_server_(talk_base::Thread::Current(), stun_socket_addr_),
-      allocator_(&network_manager_, stun_socket_addr_,
-                 SocketAddress(), SocketAddress(), SocketAddress()),
-      mediastream_signaling_(channel_manager_.get()) {
+      stun_server_(Thread::Current(), stun_socket_addr_),
+      turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
+      mediastream_signaling_(channel_manager_.get()),
+      ice_type_(PeerConnectionInterface::kAll) {
     tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
-    allocator_.set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
+
+    cricket::ServerAddresses stun_servers;
+    stun_servers.insert(stun_socket_addr_);
+    allocator_.reset(new cricket::BasicPortAllocator(
+        &network_manager_,
+        stun_servers,
+        SocketAddress(), SocketAddress(), SocketAddress()));
+    allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
                          cricket::PORTALLOCATOR_DISABLE_RELAY |
                          cricket::PORTALLOCATOR_ENABLE_BUNDLE);
     EXPECT_TRUE(channel_manager_->Init());
     desc_factory_->set_add_legacy_streams(false);
+    allocator_->set_step_delay(cricket::kMinimumStepDelay);
   }
 
   static void SetUpTestCase() {
-    talk_base::InitializeSSL();
+    rtc::InitializeSSL();
   }
 
   static void TearDownTestCase() {
-    talk_base::CleanupSSL();
+    rtc::CleanupSSL();
   }
 
   void AddInterface(const SocketAddress& addr) {
     network_manager_.AddInterface(addr);
   }
 
+  void SetIceTransportType(PeerConnectionInterface::IceTransportsType type) {
+    ice_type_ = type;
+  }
+
   void Init(DTLSIdentityServiceInterface* identity_service) {
     ASSERT_TRUE(session_.get() == NULL);
     session_.reset(new WebRtcSessionForTest(
-        channel_manager_.get(), talk_base::Thread::Current(),
-        talk_base::Thread::Current(), &allocator_,
+        channel_manager_.get(), rtc::Thread::Current(),
+        rtc::Thread::Current(), allocator_.get(),
         &observer_,
         &mediastream_signaling_));
 
@@ -323,7 +357,7 @@ class WebRtcSessionTest : public testing::Test {
         observer_.ice_gathering_state_);
 
     EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
-                                     identity_service));
+                                     identity_service, ice_type_));
   }
 
   void InitWithDtmfCodec() {
@@ -347,18 +381,26 @@ class WebRtcSessionTest : public testing::Test {
   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
   // to decide which streams to create.
   void InitiateCall() {
-    SessionDescriptionInterface* offer = CreateOffer(NULL);
+    SessionDescriptionInterface* offer = CreateOffer();
     SetLocalDescriptionWithoutError(offer);
     EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
         observer_.ice_gathering_state_,
         kIceCandidatesTimeout);
   }
 
+  SessionDescriptionInterface* CreateOffer() {
+    PeerConnectionInterface::RTCOfferAnswerOptions options;
+    options.offer_to_receive_audio =
+        RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
+
+    return CreateOffer(options);
+  }
+
   SessionDescriptionInterface* CreateOffer(
-      const webrtc::MediaConstraintsInterface* constraints) {
-    talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
+      const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
+    rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
         observer = new WebRtcSessionCreateSDPObserverForTest();
-    session_->CreateOffer(observer, constraints);
+    session_->CreateOffer(observer, options);
     EXPECT_TRUE_WAIT(
         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
         2000);
@@ -367,7 +409,7 @@ class WebRtcSessionTest : public testing::Test {
 
   SessionDescriptionInterface* CreateAnswer(
       const webrtc::MediaConstraintsInterface* constraints) {
-    talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
+    rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
         = new WebRtcSessionCreateSDPObserverForTest();
     session_->CreateAnswer(observer, constraints);
     EXPECT_TRUE_WAIT(
@@ -449,10 +491,10 @@ class WebRtcSessionTest : public testing::Test {
 
   // Set the internal fake description factories to do DTLS-SRTP.
   void SetFactoryDtlsSrtp() {
-    desc_factory_->set_secure(cricket::SEC_ENABLED);
+    desc_factory_->set_secure(cricket::SEC_DISABLED);
     std::string identity_name = "WebRTC" +
-        talk_base::ToString(talk_base::CreateRandomId());
-    identity_.reset(talk_base::SSLIdentity::Generate(identity_name));
+        rtc::ToString(rtc::CreateRandomId());
+    identity_.reset(rtc::SSLIdentity::Generate(identity_name));
     tdesc_factory_->set_identity(identity_.get());
     tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
   }
@@ -475,8 +517,8 @@ class WebRtcSessionTest : public testing::Test {
         CreateRemoteOffer(options, cricket::SEC_DISABLED));
     ASSERT_TRUE(offer != NULL);
     VerifyNoCryptoParams(offer->description(), false);
-    SetRemoteDescriptionOfferExpectError(
-        "Called with a SDP without crypto enabled", offer);
+    SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
+                                         offer);
     const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
     // Answer should be NULL as no crypto params in offer.
     ASSERT_TRUE(answer == NULL);
@@ -496,6 +538,28 @@ class WebRtcSessionTest : public testing::Test {
     VerifyCryptoParams(answer->description());
   }
 
+  void SetAndVerifyNumUnsignalledRecvStreams(
+      int value_set, int value_expected) {
+    constraints_.reset(new FakeConstraints());
+    constraints_->AddOptional(
+        webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
+        value_set);
+    session_.reset();
+    Init(NULL);
+    mediastream_signaling_.SendAudioVideoStream1();
+    SessionDescriptionInterface* offer = CreateOffer();
+
+    SetLocalDescriptionWithoutError(offer);
+
+    video_channel_ = media_engine_->GetVideoChannel(0);
+
+    ASSERT_TRUE(video_channel_ != NULL);
+    cricket::VideoOptions video_options;
+    EXPECT_TRUE(video_channel_->GetOptions(&video_options));
+    EXPECT_EQ(value_expected,
+        video_options.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(-1));
+  }
+
   void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
                                   const cricket::SessionDescription* desc2,
                                   bool expect_equal) {
@@ -540,15 +604,44 @@ class WebRtcSessionTest : public testing::Test {
           + "\r\n";
       std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
           + "\r\n";
-      talk_base::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
+      rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
                                  "", 0,
                                  sdp);
-      talk_base::replace_substrs(pwd_line.c_str(), pwd_line.length(),
+      rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
                                  "", 0,
                                  sdp);
     }
   }
 
+  void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
+                              const std::string& modified_ice_ufrag,
+                              const std::string& modified_ice_pwd,
+                              std::string* sdp) {
+    const cricket::SessionDescription* desc = current_desc->description();
+    EXPECT_TRUE(current_desc->ToString(sdp));
+
+    const cricket::ContentInfos& contents = desc->contents();
+    cricket::ContentInfos::const_iterator it = contents.begin();
+    // Replace ufrag and pwd lines with |modified_ice_ufrag| and
+    // |modified_ice_pwd| strings.
+    for (; it != contents.end(); ++it) {
+      const cricket::TransportDescription* transport_desc =
+          desc->GetTransportDescriptionByName(it->name);
+      std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
+          + "\r\n";
+      std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
+          + "\r\n";
+      std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
+      std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
+      rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
+                                 mod_ufrag.c_str(), mod_ufrag.length(),
+                                 sdp);
+      rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
+                                 mod_pwd.c_str(), mod_pwd.length(),
+                                 sdp);
+    }
+  }
+
   // Creates a remote offer and and applies it as a remote description,
   // creates a local answer and applies is as a local description.
   // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
@@ -636,12 +729,34 @@ class WebRtcSessionTest : public testing::Test {
     EXPECT_TRUE(*nocrypto_answer != NULL);
   }
 
+  void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
+      SessionDescriptionInterface** nodtls_answer) {
+    cricket::MediaSessionOptions options;
+    options.has_video = true;
+    options.bundle_enabled = true;
+
+    rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
+        CreateRemoteOffer(options, cricket::SEC_ENABLED));
+
+    *nodtls_answer =
+        CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
+    EXPECT_TRUE(*nodtls_answer != NULL);
+    VerifyFingerprintStatus((*nodtls_answer)->description(), false);
+    VerifyCryptoParams((*nodtls_answer)->description());
+
+    SetFactoryDtlsSrtp();
+    *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
+    ASSERT_TRUE(*offer != NULL);
+    VerifyFingerprintStatus((*offer)->description(), true);
+    VerifyCryptoParams((*offer)->description());
+  }
+
   JsepSessionDescription* CreateRemoteOfferWithVersion(
         cricket::MediaSessionOptions options,
         cricket::SecurePolicy secure_policy,
         const std::string& session_version,
         const SessionDescriptionInterface* current_desc) {
-    std::string session_id = talk_base::ToString(talk_base::CreateRandomId64());
+    std::string session_id = rtc::ToString(rtc::CreateRandomId64());
     const cricket::SessionDescription* cricket_desc = NULL;
     if (current_desc) {
       cricket_desc = current_desc->description();
@@ -664,8 +779,9 @@ class WebRtcSessionTest : public testing::Test {
                                         kSessionVersion, NULL);
   }
   JsepSessionDescription* CreateRemoteOffer(
-      cricket::MediaSessionOptions options, cricket::SecurePolicy policy) {
-    return CreateRemoteOfferWithVersion(options, policy, kSessionVersion, NULL);
+      cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
+    return CreateRemoteOfferWithVersion(
+        options, sdes_policy, kSessionVersion, NULL);
   }
   JsepSessionDescription* CreateRemoteOffer(
       cricket::MediaSessionOptions options,
@@ -690,10 +806,10 @@ class WebRtcSessionTest : public testing::Test {
     // SessionDescription from the mutated string.
     const char* default_port_str = "5000";
     char new_port_str[16];
-    talk_base::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
+    rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
     std::string offer_str;
     offer_basis->ToString(&offer_str);
-    talk_base::replace_substrs(default_port_str, strlen(default_port_str),
+    rtc::replace_substrs(default_port_str, strlen(default_port_str),
                                new_port_str, strlen(new_port_str),
                                &offer_str);
     JsepSessionDescription* offer = new JsepSessionDescription(
@@ -717,7 +833,7 @@ class WebRtcSessionTest : public testing::Test {
       cricket::SecurePolicy policy) {
     desc_factory_->set_secure(policy);
     const std::string session_id =
-        talk_base::ToString(talk_base::CreateRandomId64());
+        rtc::ToString(rtc::CreateRandomId64());
     JsepSessionDescription* answer(
         new JsepSessionDescription(JsepSessionDescription::kAnswer));
     if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
@@ -747,17 +863,19 @@ class WebRtcSessionTest : public testing::Test {
   }
 
   void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
-    AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+    AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
     Init(NULL);
     mediastream_signaling_.SendAudioVideoStream1();
-    FakeConstraints constraints;
-    constraints.SetMandatoryUseRtpMux(bundle);
-    SessionDescriptionInterface* offer = CreateOffer(&constraints);
+
+    PeerConnectionInterface::RTCOfferAnswerOptions options;
+    options.use_rtp_mux = bundle;
+
+    SessionDescriptionInterface* offer = CreateOffer(options);
     // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
     // and answer.
     SetLocalDescriptionWithoutError(offer);
 
-    talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+    rtc::scoped_ptr<SessionDescriptionInterface> answer(
         CreateRemoteAnswer(session_->local_description()));
     std::string sdp;
     EXPECT_TRUE(answer->ToString(&sdp));
@@ -770,7 +888,7 @@ class WebRtcSessionTest : public testing::Test {
       // Disable rtcp-mux from the answer
       const std::string kRtcpMux = "a=rtcp-mux";
       const std::string kXRtcpMux = "a=xrtcp-mux";
-      talk_base::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
+      rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
                                  kXRtcpMux.c_str(), kXRtcpMux.length(),
                                  &sdp);
     }
@@ -819,10 +937,10 @@ class WebRtcSessionTest : public testing::Test {
   //     -> Failed.
   // The Gathering state should go: New -> Gathering -> Completed.
   void TestLoopbackCall() {
-    AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+    AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
     Init(NULL);
     mediastream_signaling_.SendAudioVideoStream1();
-    SessionDescriptionInterface* offer = CreateOffer(NULL);
+    SessionDescriptionInterface* offer = CreateOffer();
 
     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
               observer_.ice_gathering_state_);
@@ -847,6 +965,7 @@ class WebRtcSessionTest : public testing::Test {
     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
                    observer_.ice_connection_state_,
                    kIceCandidatesTimeout);
+
     // The ice connection state is "Connected" too briefly to catch in a test.
     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
                    observer_.ice_connection_state_,
@@ -855,9 +974,9 @@ class WebRtcSessionTest : public testing::Test {
     // Adding firewall rule to block ping requests, which should cause
     // transport channel failure.
     fss_->AddRule(false,
-                  talk_base::FP_ANY,
-                  talk_base::FD_ANY,
-                  talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+                  rtc::FP_ANY,
+                  rtc::FD_ANY,
+                  rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
                    observer_.ice_connection_state_,
                    kIceCandidatesTimeout);
@@ -876,9 +995,9 @@ class WebRtcSessionTest : public testing::Test {
     // wait for the Port to timeout.
     int port_timeout = 30000;
     fss_->AddRule(false,
-                  talk_base::FP_ANY,
-                  talk_base::FD_ANY,
-                  talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+                  rtc::FP_ANY,
+                  rtc::FD_ANY,
+                  rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
     EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
                    observer_.ice_connection_state_,
                    kIceCandidatesTimeout + port_timeout);
@@ -921,29 +1040,30 @@ class WebRtcSessionTest : public testing::Test {
     webrtc::InternalDataChannelInit dci;
     dci.reliable = false;
     session_->CreateDataChannel("datachannel", &dci);
-    SessionDescriptionInterface* offer = CreateOffer(NULL);
+    SessionDescriptionInterface* offer = CreateOffer();
     SetLocalDescriptionWithoutError(offer);
   }
 
   void VerifyMultipleAsyncCreateDescription(
       bool success, CreateSessionDescriptionRequest::Type type) {
     InitWithDtls(!success);
-
+    SetFactoryDtlsSrtp();
     if (type == CreateSessionDescriptionRequest::kAnswer) {
       cricket::MediaSessionOptions options;
       scoped_ptr<JsepSessionDescription> offer(
-            CreateRemoteOffer(options, cricket::SEC_REQUIRED));
+            CreateRemoteOffer(options, cricket::SEC_DISABLED));
       ASSERT_TRUE(offer.get() != NULL);
       SetRemoteDescriptionWithoutError(offer.release());
     }
 
+    PeerConnectionInterface::RTCOfferAnswerOptions options;
     const int kNumber = 3;
-    talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
+    rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
         observers[kNumber];
     for (int i = 0; i < kNumber; ++i) {
       observers[i] = new WebRtcSessionCreateSDPObserverForTest();
       if (type == CreateSessionDescriptionRequest::kOffer) {
-        session_->CreateOffer(observers[i], NULL);
+        session_->CreateOffer(observers[i], options);
       } else {
         session_->CreateAnswer(observers[i], NULL);
       }
@@ -966,39 +1086,39 @@ class WebRtcSessionTest : public testing::Test {
   cricket::FakeMediaEngine* media_engine_;
   cricket::FakeDataEngine* data_engine_;
   cricket::FakeDeviceManager* device_manager_;
-  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
-  talk_base::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
-  talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
-  talk_base::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
-  talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
-  talk_base::SocketServerScope ss_scope_;
-  talk_base::SocketAddress stun_socket_addr_;
+  rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
+  rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
+  rtc::scoped_ptr<rtc::SSLIdentity> identity_;
+  rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
+  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+  rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
+  rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
+  rtc::SocketServerScope ss_scope_;
+  rtc::SocketAddress stun_socket_addr_;
   cricket::TestStunServer stun_server_;
-  talk_base::FakeNetworkManager network_manager_;
-  cricket::BasicPortAllocator allocator_;
+  cricket::TestTurnServer turn_server_;
+  rtc::FakeNetworkManager network_manager_;
+  rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
   PeerConnectionFactoryInterface::Options options_;
-  talk_base::scoped_ptr<FakeConstraints> constraints_;
+  rtc::scoped_ptr<FakeConstraints> constraints_;
   FakeMediaStreamSignaling mediastream_signaling_;
-  talk_base::scoped_ptr<WebRtcSessionForTest> session_;
+  rtc::scoped_ptr<WebRtcSessionForTest> session_;
   MockIceObserver observer_;
   cricket::FakeVideoMediaChannel* video_channel_;
   cricket::FakeVoiceMediaChannel* voice_channel_;
+  PeerConnectionInterface::IceTransportsType ice_type_;
 };
 
-TEST_F(WebRtcSessionTest, TestInitialize) {
-  Init(NULL);
-}
-
 TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
   InitWithDtls();
+  // SDES is disabled when DTLS is on.
+  EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
 }
 
-// Verifies that WebRtcSession uses SEC_REQUIRED by default.
-TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
+TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
   Init(NULL);
-  EXPECT_EQ(cricket::SEC_REQUIRED, session_->SecurePolicy());
+  // SDES is required if DTLS is off.
+  EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
 }
 
 TEST_F(WebRtcSessionTest, TestSessionCandidates) {
@@ -1016,8 +1136,8 @@ TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
 }
 
 TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
-  AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
-  AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
   InitiateCall();
@@ -1027,12 +1147,12 @@ TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
 }
 
 TEST_F(WebRtcSessionTest, TestStunError) {
-  AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
-  AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
   fss_->AddRule(false,
-                talk_base::FP_UDP,
-                talk_base::FD_ANY,
-                talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+                rtc::FP_UDP,
+                rtc::FD_ANY,
+                rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
   InitiateCall();
@@ -1053,10 +1173,10 @@ TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
 
 // Test creating offers and receive answers and make sure the
 // media engine creates the expected send and receive streams.
-TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
+TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   const std::string session_id_orig = offer->session_id();
   const std::string session_version_orig = offer->session_version();
   SetLocalDescriptionWithoutError(offer);
@@ -1082,13 +1202,13 @@ TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
 
   // Create new offer without send streams.
   mediastream_signaling_.SendNothing();
-  offer = CreateOffer(NULL);
+  offer = CreateOffer();
 
   // Verify the session id is the same and the session version is
   // increased.
   EXPECT_EQ(session_id_orig, offer->session_id());
-  EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
-            talk_base::FromString<uint64>(offer->session_version()));
+  EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
+            rtc::FromString<uint64>(offer->session_version()));
 
   SetLocalDescriptionWithoutError(offer);
 
@@ -1108,14 +1228,16 @@ TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
 
 // Test receiving offers and creating answers and make sure the
 // media engine creates the expected send and receive streams.
-TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
+TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream2();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
+  VerifyCryptoParams(offer->description());
   SetRemoteDescriptionWithoutError(offer);
 
   mediastream_signaling_.SendAudioVideoStream1();
   SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  VerifyCryptoParams(answer->description());
   SetLocalDescriptionWithoutError(answer);
 
   const std::string session_id_orig = answer->session_id();
@@ -1136,7 +1258,7 @@ TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
   EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
 
   mediastream_signaling_.SendAudioVideoStream1And2();
-  offer = CreateOffer(NULL);
+  offer = CreateOffer();
   SetRemoteDescriptionWithoutError(offer);
 
   // Answer by turning off all send streams.
@@ -1146,8 +1268,8 @@ TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
   // Verify the session id is the same and the session version is
   // increased.
   EXPECT_EQ(session_id_orig, answer->session_id());
-  EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
-            talk_base::FromString<uint64>(answer->session_version()));
+  EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
+            rtc::FromString<uint64>(answer->session_version()));
   SetLocalDescriptionWithoutError(answer);
 
   ASSERT_EQ(2u, video_channel_->recv_streams().size());
@@ -1166,19 +1288,49 @@ TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
   Init(NULL);
   media_engine_->set_fail_create_channel(true);
 
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   ASSERT_TRUE(offer != NULL);
   // SetRemoteDescription and SetLocalDescription will take the ownership of
   // the offer.
   SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
-  offer = CreateOffer(NULL);
+  offer = CreateOffer();
   ASSERT_TRUE(offer != NULL);
   SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
 }
 
-// Test we will return fail when apply an offer that doesn't have
-// crypto enabled.
-TEST_F(WebRtcSessionTest, SetNonCryptoOffer) {
+//
+// Tests for creating/setting SDP under different SDES/DTLS polices:
+//
+// --DTLS off and SDES on
+// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
+//     set local/remote offer/answer with crypto --> success
+// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
+//     failure
+// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
+//     failure
+// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
+//     failure
+//
+// --DTLS on and SDES off
+// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
+//     set local/remote offer/answer with DTLS fingerprint --> success
+// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
+//     fingerprint --> failure
+// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
+//     --> failure
+// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
+//     --> failure
+//
+// --Encryption disabled: DTLS off and SDES off
+// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
+//     answer without SDES or DTLS --> success
+// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
+//     answer without SDES or DTLS --> success
+//
+
+// Test that we return a failure when applying a remote/local offer that doesn't
+// have cryptos enabled when DTLS is off.
+TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
   Init(NULL);
   cricket::MediaSessionOptions options;
   options.has_video = true;
@@ -1188,15 +1340,15 @@ TEST_F(WebRtcSessionTest, SetNonCryptoOffer) {
   VerifyNoCryptoParams(offer->description(), false);
   // SetRemoteDescription and SetLocalDescription will take the ownership of
   // the offer.
-  SetRemoteDescriptionOfferExpectError(kSdpWithoutCrypto, offer);
+  SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
   offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
   ASSERT_TRUE(offer != NULL);
-  SetLocalDescriptionOfferExpectError(kSdpWithoutCrypto, offer);
+  SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
 }
 
-// Test we will return fail when apply an answer that doesn't have
-// crypto enabled.
-TEST_F(WebRtcSessionTest, SetLocalNonCryptoAnswer) {
+// Test that we return a failure when applying a local answer that doesn't have
+// cryptos enabled when DTLS is off.
+TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
   Init(NULL);
   SessionDescriptionInterface* offer = NULL;
   SessionDescriptionInterface* answer = NULL;
@@ -1204,12 +1356,12 @@ TEST_F(WebRtcSessionTest, SetLocalNonCryptoAnswer) {
   // SetRemoteDescription and SetLocalDescription will take the ownership of
   // the offer.
   SetRemoteDescriptionWithoutError(offer);
-  SetLocalDescriptionAnswerExpectError(kSdpWithoutCrypto, answer);
+  SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
 }
 
-// Test we will return fail when apply an answer that doesn't have
-// crypto enabled.
-TEST_F(WebRtcSessionTest, SetRemoteNonCryptoAnswer) {
+// Test we will return fail when apply an remote answer that doesn't have
+// crypto enabled when DTLS is off.
+TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
   Init(NULL);
   SessionDescriptionInterface* offer = NULL;
   SessionDescriptionInterface* answer = NULL;
@@ -1217,32 +1369,23 @@ TEST_F(WebRtcSessionTest, SetRemoteNonCryptoAnswer) {
   // SetRemoteDescription and SetLocalDescription will take the ownership of
   // the offer.
   SetLocalDescriptionWithoutError(offer);
-  SetRemoteDescriptionAnswerExpectError(kSdpWithoutCrypto, answer);
+  SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
 }
 
-// Test that we can create and set an offer with a DTLS fingerprint.
-TEST_F(WebRtcSessionTest, CreateSetDtlsOffer) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
-  InitWithDtls();
+// Test that we accept an offer with a DTLS fingerprint when DTLS is on
+// and that we return an answer with a DTLS fingerprint.
+TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
-  ASSERT_TRUE(offer != NULL);
-  VerifyFingerprintStatus(offer->description(), true);
-  // SetLocalDescription will take the ownership of the offer.
-  SetLocalDescriptionWithoutError(offer);
-}
-
-// Test that we can process an offer with a DTLS fingerprint
-// and that we return an answer with a fingerprint.
-TEST_F(WebRtcSessionTest, ReceiveDtlsOfferCreateAnswer) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtls();
   SetFactoryDtlsSrtp();
   cricket::MediaSessionOptions options;
   options.has_video = true;
-  JsepSessionDescription* offer = CreateRemoteOffer(options);
+  JsepSessionDescription* offer =
+      CreateRemoteOffer(options, cricket::SEC_DISABLED);
   ASSERT_TRUE(offer != NULL);
   VerifyFingerprintStatus(offer->description(), true);
+  VerifyNoCryptoParams(offer->description(), true);
 
   // SetRemoteDescription will take the ownership of the offer.
   SetRemoteDescriptionWithoutError(offer);
@@ -1258,28 +1401,148 @@ TEST_F(WebRtcSessionTest, ReceiveDtlsOfferCreateAnswer) {
   SetLocalDescriptionWithoutError(answer);
 }
 
-// Test that even if we support DTLS, if the other side didn't offer a
-// fingerprint, we don't either.
-TEST_F(WebRtcSessionTest, ReceiveNoDtlsOfferCreateAnswer) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+// Test that we set a local offer with a DTLS fingerprint when DTLS is on
+// and then we accept a remote answer with a DTLS fingerprint successfully.
+TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  mediastream_signaling_.SendAudioVideoStream1();
+  InitWithDtls();
+  SetFactoryDtlsSrtp();
+
+  // Verify that we get a crypto fingerprint in the answer.
+  SessionDescriptionInterface* offer = CreateOffer();
+  ASSERT_TRUE(offer != NULL);
+  VerifyFingerprintStatus(offer->description(), true);
+  // Check that we don't have an a=crypto line in the offer.
+  VerifyNoCryptoParams(offer->description(), true);
+
+  // Now set the local description, which should work, even without a=crypto.
+  SetLocalDescriptionWithoutError(offer);
+
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  JsepSessionDescription* answer =
+      CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
+  ASSERT_TRUE(answer != NULL);
+  VerifyFingerprintStatus(answer->description(), true);
+  VerifyNoCryptoParams(answer->description(), true);
+
+  // SetRemoteDescription will take the ownership of the answer.
+  SetRemoteDescriptionWithoutError(answer);
+}
+
+// Test that if we support DTLS and the other side didn't offer a fingerprint,
+// we will fail to set the remote description.
+TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtls();
   cricket::MediaSessionOptions options;
   options.has_video = true;
+  options.bundle_enabled = true;
   JsepSessionDescription* offer = CreateRemoteOffer(
       options, cricket::SEC_REQUIRED);
   ASSERT_TRUE(offer != NULL);
   VerifyFingerprintStatus(offer->description(), false);
+  VerifyCryptoParams(offer->description());
 
-  // SetRemoteDescription will take the ownership of
-  // the offer.
+  // SetRemoteDescription will take the ownership of the offer.
+  SetRemoteDescriptionOfferExpectError(
+      kSdpWithoutDtlsFingerprint, offer);
+
+  offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
+  // SetLocalDescription will take the ownership of the offer.
+  SetLocalDescriptionOfferExpectError(
+      kSdpWithoutDtlsFingerprint, offer);
+}
+
+// Test that we return a failure when applying a local answer that doesn't have
+// a DTLS fingerprint when DTLS is required.
+TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
+  SessionDescriptionInterface* offer = NULL;
+  SessionDescriptionInterface* answer = NULL;
+  CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
+
+  // SetRemoteDescription and SetLocalDescription will take the ownership of
+  // the offer and answer.
+  SetRemoteDescriptionWithoutError(offer);
+  SetLocalDescriptionAnswerExpectError(
+      kSdpWithoutDtlsFingerprint, answer);
+}
+
+// Test that we return a failure when applying a remote answer that doesn't have
+// a DTLS fingerprint when DTLS is required.
+TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
+  SessionDescriptionInterface* offer = CreateOffer();
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  JsepSessionDescription* answer =
+      CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
+
+  // SetRemoteDescription and SetLocalDescription will take the ownership of
+  // the offer and answer.
+  SetLocalDescriptionWithoutError(offer);
+  SetRemoteDescriptionAnswerExpectError(
+      kSdpWithoutDtlsFingerprint, answer);
+}
+
+// Test that we create a local offer without SDES or DTLS and accept a remote
+// answer without SDES or DTLS when encryption is disabled.
+TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
+  mediastream_signaling_.SendAudioVideoStream1();
+  options_.disable_encryption = true;
+  InitWithDtls();
+
+  // Verify that we get a crypto fingerprint in the answer.
+  SessionDescriptionInterface* offer = CreateOffer();
+  ASSERT_TRUE(offer != NULL);
+  VerifyFingerprintStatus(offer->description(), false);
+  // Check that we don't have an a=crypto line in the offer.
+  VerifyNoCryptoParams(offer->description(), false);
+
+  // Now set the local description, which should work, even without a=crypto.
+  SetLocalDescriptionWithoutError(offer);
+
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  JsepSessionDescription* answer =
+      CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
+  ASSERT_TRUE(answer != NULL);
+  VerifyFingerprintStatus(answer->description(), false);
+  VerifyNoCryptoParams(answer->description(), false);
+
+  // SetRemoteDescription will take the ownership of the answer.
+  SetRemoteDescriptionWithoutError(answer);
+}
+
+// Test that we create a local answer without SDES or DTLS and accept a remote
+// offer without SDES or DTLS when encryption is disabled.
+TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
+  options_.disable_encryption = true;
+  InitWithDtls();
+
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  JsepSessionDescription* offer =
+      CreateRemoteOffer(options, cricket::SEC_DISABLED);
+  ASSERT_TRUE(offer != NULL);
+  VerifyFingerprintStatus(offer->description(), false);
+  VerifyNoCryptoParams(offer->description(), false);
+
+  // SetRemoteDescription will take the ownership of the offer.
   SetRemoteDescriptionWithoutError(offer);
 
-  // Verify that we don't get a crypto fingerprint in the answer.
+  // Verify that we get a crypto fingerprint in the answer.
   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   ASSERT_TRUE(answer != NULL);
   VerifyFingerprintStatus(answer->description(), false);
+  // Check that we don't have an a=crypto line in the answer.
+  VerifyNoCryptoParams(answer->description(), false);
 
-  // Now set the local description.
+  // Now set the local description, which should work, even without a=crypto.
   SetLocalDescriptionWithoutError(answer);
 }
 
@@ -1287,11 +1550,11 @@ TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
   // SetLocalDescription take ownership of offer.
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionWithoutError(offer);
 
   // SetLocalDescription take ownership of offer.
-  SessionDescriptionInterface* offer2 = CreateOffer(NULL);
+  SessionDescriptionInterface* offer2 = CreateOffer();
   SetLocalDescriptionWithoutError(offer2);
 }
 
@@ -1299,19 +1562,19 @@ TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
   // SetLocalDescription take ownership of offer.
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetRemoteDescriptionWithoutError(offer);
 
-  SessionDescriptionInterface* offer2 = CreateOffer(NULL);
+  SessionDescriptionInterface* offer2 = CreateOffer();
   SetRemoteDescriptionWithoutError(offer2);
 }
 
 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionWithoutError(offer);
-  offer = CreateOffer(NULL);
+  offer = CreateOffer();
   SetRemoteDescriptionOfferExpectError(
       "Called in wrong state: STATE_SENTINITIATE", offer);
 }
@@ -1319,9 +1582,9 @@ TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
 TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetRemoteDescriptionWithoutError(offer);
-  offer = CreateOffer(NULL);
+  offer = CreateOffer();
   SetLocalDescriptionOfferExpectError(
       "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
 }
@@ -1352,7 +1615,7 @@ TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
 TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
 
   JsepSessionDescription* pranswer =
@@ -1379,8 +1642,8 @@ TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
 TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   SessionDescriptionInterface* answer =
       CreateRemoteAnswer(offer.get());
   SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
@@ -1390,8 +1653,8 @@ TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
 TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
   Init(NULL);
   mediastream_signaling_.SendNothing();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-        CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   SessionDescriptionInterface* answer =
       CreateRemoteAnswer(offer.get());
   SetRemoteDescriptionAnswerExpectError(
@@ -1409,7 +1672,7 @@ TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
   // Fail since we have not set a offer description.
   EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
 
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionWithoutError(offer);
   // Candidate should be allowed to add before remote description.
   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
@@ -1500,7 +1763,7 @@ TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
 // Test that local candidates are added to the local session description and
 // that they are retained if the local session description is changed.
 TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
-  AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
   CreateAndSetRemoteOfferAndLocalAnswer();
@@ -1543,7 +1806,7 @@ TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
   JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
                                  candidate1);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
 
   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   SetRemoteDescriptionWithoutError(offer);
@@ -1564,7 +1827,7 @@ TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
 // Test that offers and answers contains ice candidates when Ice candidates have
 // been gathered.
 TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
-  AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+  AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
   // Ice is started but candidates are not provided until SetLocalDescription
@@ -1578,8 +1841,8 @@ TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
   EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
                    kIceCandidatesTimeout);
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> local_offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
+
   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
   EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
   ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
@@ -1600,8 +1863,7 @@ TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
 TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
 
   // CreateOffer creates session description with the content names "audio" and
   // "video". Goal is to modify these content names and verify transport channel
@@ -1615,12 +1877,12 @@ TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
   const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
 
   // Replacing |audio| with |audio_content_name|.
-  talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
+  rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
                              kAudioMidReplaceStr.c_str(),
                              kAudioMidReplaceStr.length(),
                              &sdp);
   // Replacing |video| with |video_content_name|.
-  talk_base::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
+  rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
                              kVideoMidReplaceStr.c_str(),
                              kVideoMidReplaceStr.length(),
                              &sdp);
@@ -1644,8 +1906,8 @@ TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
 // the send streams when no constraints have been set.
 TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
   Init(NULL);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   ASSERT_TRUE(offer != NULL);
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
@@ -1660,8 +1922,8 @@ TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
   Init(NULL);
   // Test Audio only offer.
   mediastream_signaling_.UseOptionsAudioOnly();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-        CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
   EXPECT_TRUE(content != NULL);
@@ -1670,7 +1932,7 @@ TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
 
   // Test Audio / Video offer.
   mediastream_signaling_.SendAudioVideoStream1();
-  offer.reset(CreateOffer(NULL));
+  offer.reset(CreateOffer());
   content = cricket::GetFirstAudioContent(offer->description());
   EXPECT_TRUE(content != NULL);
   content = cricket::GetFirstVideoContent(offer->description());
@@ -1681,12 +1943,13 @@ TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
 // kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
 TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
   Init(NULL);
-  webrtc::FakeConstraints constraints_no_receive;
-  constraints_no_receive.SetMandatoryReceiveAudio(false);
-  constraints_no_receive.SetMandatoryReceiveVideo(false);
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.offer_to_receive_audio = 0;
+  options.offer_to_receive_video = 0;
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(
+      CreateOffer(options));
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(&constraints_no_receive));
   ASSERT_TRUE(offer != NULL);
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
@@ -1699,10 +1962,12 @@ TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
 // kOfferToReceiveAudio constraints are set to true.
 TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
   Init(NULL);
-  webrtc::FakeConstraints constraints_audio_only;
-  constraints_audio_only.SetMandatoryReceiveAudio(true);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-        CreateOffer(&constraints_audio_only));
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.offer_to_receive_audio =
+      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(
+        CreateOffer(options));
 
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
@@ -1716,11 +1981,15 @@ TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
 TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
   Init(NULL);
   // Test Audio / Video offer.
-  webrtc::FakeConstraints constraints_audio_video;
-  constraints_audio_video.SetMandatoryReceiveAudio(true);
-  constraints_audio_video.SetMandatoryReceiveVideo(true);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(&constraints_audio_video));
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.offer_to_receive_audio =
+      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
+  options.offer_to_receive_video =
+      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(
+      CreateOffer(options));
+
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
 
@@ -1736,7 +2005,7 @@ TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
 // an offer.
 TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
   Init(NULL);
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionWithoutError(offer);
   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   SetRemoteDescriptionWithoutError(answer);
@@ -1748,9 +2017,9 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
   Init(NULL);
   // Create a remote offer with audio and video content.
-  talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
@@ -1770,13 +2039,13 @@ TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
   cricket::MediaSessionOptions options;
   options.has_audio = true;
   options.has_video = false;
-  talk_base::scoped_ptr<JsepSessionDescription> offer(
+  rtc::scoped_ptr<JsepSessionDescription> offer(
       CreateRemoteOffer(options));
   ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
   ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
 
   SetRemoteDescriptionWithoutError(offer.release());
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
@@ -1791,11 +2060,11 @@ TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
 TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
   Init(NULL);
   // Create a remote offer with audio and video content.
-  talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
   // Test with a stream with tracks.
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
@@ -1812,14 +2081,14 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
   Init(NULL);
   // Create a remote offer with audio and video content.
-  talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
   webrtc::FakeConstraints constraints_no_receive;
   constraints_no_receive.SetMandatoryReceiveAudio(false);
   constraints_no_receive.SetMandatoryReceiveVideo(false);
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(&constraints_no_receive));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
@@ -1836,7 +2105,7 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
 TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
   Init(NULL);
   // Create a remote offer with audio and video content.
-  talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
   webrtc::FakeConstraints constraints_no_receive;
@@ -1845,7 +2114,7 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
 
   // Test with a stream with tracks.
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(&constraints_no_receive));
 
   // TODO(perkj): Should the direction be set to SEND_ONLY?
@@ -1863,10 +2132,14 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
 TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
   AddCNCodecs();
   Init(NULL);
-  webrtc::FakeConstraints constraints;
-  constraints.SetOptionalVAD(false);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(&constraints));
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.offer_to_receive_audio =
+      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
+  options.voice_activity_detection = false;
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(
+      CreateOffer(options));
+
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(offer->description());
   EXPECT_TRUE(content != NULL);
@@ -1877,12 +2150,12 @@ TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
   AddCNCodecs();
   Init(NULL);
   // Create a remote offer with audio and video content.
-  talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
   webrtc::FakeConstraints constraints;
   constraints.SetOptionalVAD(false);
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(&constraints));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
@@ -1898,7 +2171,7 @@ TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
 
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
 
   cricket::MediaSessionOptions options;
   options.has_video = false;
@@ -1955,7 +2228,7 @@ TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
   EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
   EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
 
   cricket::MediaSessionOptions options;
   options.has_audio = false;
@@ -2006,8 +2279,7 @@ TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
 TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   VerifyCryptoParams(offer->description());
   SetRemoteDescriptionWithoutError(offer.release());
   scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
@@ -2018,8 +2290,7 @@ TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
   options_.disable_encryption = true;
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  scoped_ptr<SessionDescriptionInterface> offer(
-        CreateOffer(NULL));
+  scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   VerifyNoCryptoParams(offer->description(), false);
 }
 
@@ -2038,7 +2309,8 @@ TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
 TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   std::string sdp;
   RemoveIceUfragPwdLines(offer.get(), &sdp);
   SessionDescriptionInterface* modified_offer =
@@ -2050,7 +2322,7 @@ TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
 // no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
 TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
   Init(NULL);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
   std::string sdp;
   RemoveIceUfragPwdLines(offer.get(), &sdp);
   SessionDescriptionInterface* modified_offer =
@@ -2058,15 +2330,64 @@ TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
   SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
 }
 
+// This test verifies that setLocalDescription fails if local offer has
+// too short ice ufrag and pwd strings.
+TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
+  Init(NULL);
+  tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
+  mediastream_signaling_.SendAudioVideoStream1();
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
+  std::string sdp;
+  // Modifying ice ufrag and pwd in local offer with strings smaller than the
+  // recommended values of 4 and 22 bytes respectively.
+  ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
+  SessionDescriptionInterface* modified_offer =
+      CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
+  std::string error;
+  EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
+
+  // Test with string greater than 256.
+  sdp.clear();
+  ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
+                         &sdp);
+  modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
+                                            NULL);
+  EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
+}
+
+// This test verifies that setRemoteDescription fails if remote offer has
+// too short ice ufrag and pwd strings.
+TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
+  Init(NULL);
+  tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
+  std::string sdp;
+  // Modifying ice ufrag and pwd in remote offer with strings smaller than the
+  // recommended values of 4 and 22 bytes respectively.
+  ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
+  SessionDescriptionInterface* modified_offer =
+     CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
+  std::string error;
+  EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
+
+  sdp.clear();
+  ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
+                         &sdp);
+  modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
+                                            NULL);
+  EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
+}
+
 TEST_F(WebRtcSessionTest, VerifyBundleFlagInPA) {
   // This test verifies BUNDLE flag in PortAllocator, if BUNDLE information in
   // local description is removed by the application, BUNDLE flag should be
   // disabled in PortAllocator. By default BUNDLE is enabled in the WebRtc.
   Init(NULL);
-  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
-      cricket::PORTALLOCATOR_ENABLE_BUNDLE);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
+      allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   cricket::SessionDescription* offer_copy =
       offer->description()->Copy();
   offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
@@ -2075,20 +2396,23 @@ TEST_F(WebRtcSessionTest, VerifyBundleFlagInPA) {
   modified_offer->Initialize(offer_copy, "1", "1");
 
   SetLocalDescriptionWithoutError(modified_offer);
-  EXPECT_FALSE(allocator_.flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+  EXPECT_FALSE(allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE);
 }
 
 TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
-      cricket::PORTALLOCATOR_ENABLE_BUNDLE);
-  FakeConstraints constraints;
-  constraints.SetMandatoryUseRtpMux(true);
-  SessionDescriptionInterface* offer = CreateOffer(&constraints);
+  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
+      allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.use_rtp_mux = true;
+
+  SessionDescriptionInterface* offer = CreateOffer(options);
+
   SetLocalDescriptionWithoutError(offer);
   mediastream_signaling_.SendAudioVideoStream2();
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateRemoteAnswer(session_->local_description()));
   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
@@ -2096,8 +2420,8 @@ TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
       new JsepSessionDescription(JsepSessionDescription::kAnswer);
   modified_answer->Initialize(answer_copy, "1", "1");
   SetRemoteDescriptionWithoutError(modified_answer);
-  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
-      cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
+      allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
 
   video_channel_ = media_engine_->GetVideoChannel(0);
   voice_channel_ = media_engine_->GetVoiceChannel(0);
@@ -2119,17 +2443,19 @@ TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
 TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
   WebRtcSessionTest::Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
-      cricket::PORTALLOCATOR_ENABLE_BUNDLE);
-  FakeConstraints constraints;
-  constraints.SetMandatoryUseRtpMux(true);
-  SessionDescriptionInterface* offer = CreateOffer(&constraints);
+  EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE &
+      allocator_->flags()) == cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+  PeerConnectionInterface::RTCOfferAnswerOptions options;
+  options.use_rtp_mux = true;
+
+  SessionDescriptionInterface* offer = CreateOffer(options);
   std::string offer_str;
   offer->ToString(&offer_str);
   // Disable rtcp-mux
   const std::string rtcp_mux = "rtcp-mux";
   const std::string xrtcp_mux = "xrtcp-mux";
-  talk_base::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
+  rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
                              xrtcp_mux.c_str(), xrtcp_mux.length(),
                              &offer_str);
   JsepSessionDescription *local_offer =
@@ -2156,7 +2482,7 @@ TEST_F(WebRtcSessionTest, SetAudioPlayout) {
   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
   EXPECT_EQ(1, left_vol);
   EXPECT_EQ(1, right_vol);
-  talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
+  rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
   EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
   EXPECT_EQ(0, left_vol);
@@ -2182,18 +2508,44 @@ TEST_F(WebRtcSessionTest, SetAudioSend) {
   cricket::AudioOptions options;
   options.echo_cancellation.Set(true);
 
-  talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
+  rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
   session_->SetAudioSend(send_ssrc, false, options, renderer.get());
   EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
   EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
   EXPECT_EQ(0, renderer->channel_id());
+  EXPECT_TRUE(renderer->sink() != NULL);
 
+  // This will trigger SetSink(NULL) to the |renderer|.
   session_->SetAudioSend(send_ssrc, true, options, NULL);
   EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
   bool value;
   EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
   EXPECT_TRUE(value);
   EXPECT_EQ(-1, renderer->channel_id());
+  EXPECT_TRUE(renderer->sink() == NULL);
+}
+
+TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
+  Init(NULL);
+  mediastream_signaling_.SendAudioVideoStream1();
+  CreateAndSetRemoteOfferAndLocalAnswer();
+  cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
+  ASSERT_TRUE(channel != NULL);
+  ASSERT_EQ(1u, channel->send_streams().size());
+  uint32 send_ssrc  = channel->send_streams()[0].first_ssrc();
+
+  rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
+  cricket::AudioOptions options;
+  session_->SetAudioSend(send_ssrc, true, options, renderer.get());
+  EXPECT_TRUE(renderer->sink() != NULL);
+
+  // Delete the |renderer| and it will trigger OnClose() to the sink, and this
+  // will invalidate the |renderer_| pointer in the sink and prevent getting a
+  // SetSink(NULL) callback afterwards.
+  renderer.reset();
+
+  // This will trigger SetSink(NULL) if no OnClose() callback.
+  session_->SetAudioSend(send_ssrc, true, options, NULL);
 }
 
 TEST_F(WebRtcSessionTest, SetVideoPlayout) {
@@ -2267,7 +2619,7 @@ TEST_F(WebRtcSessionTest, InsertDtmf) {
 TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
   Init(NULL);
   EXPECT_FALSE(session_->initiator());
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   SetLocalDescriptionWithoutError(offer);
   EXPECT_TRUE(session_->initiator());
@@ -2293,8 +2645,8 @@ TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
 TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  SessionDescriptionInterface* offer = CreateOffer();
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateRemoteAnswer(offer));
   SetLocalDescriptionWithoutError(offer);
   std::string sdp;
@@ -2315,7 +2667,7 @@ TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
 TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   SetLocalDescriptionWithoutError(offer);
 
@@ -2329,9 +2681,9 @@ TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
 TEST_F(WebRtcSessionTest, TestReceiverGIceInOffer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetRemoteDescriptionWithoutError(offer);
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   std::string sdp;
   EXPECT_TRUE(answer->ToString(&sdp));
@@ -2351,7 +2703,7 @@ TEST_F(WebRtcSessionTest, TestReceiverGIceInOffer) {
 TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetRemoteDescriptionWithoutError(offer);
   SessionDescriptionInterface* answer = CreateAnswer(NULL);
   SetLocalDescriptionWithoutError(answer);
@@ -2364,14 +2716,14 @@ TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
 TEST_F(WebRtcSessionTest, TestIceOfferGIceOnlyAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   std::string offer_str;
   offer->ToString(&offer_str);
   // Disable google-ice
   const std::string gice_option = "google-ice";
   const std::string xgoogle_xice = "xgoogle-xice";
-  talk_base::replace_substrs(gice_option.c_str(), gice_option.length(),
+  rtc::replace_substrs(gice_option.c_str(), gice_option.length(),
                              xgoogle_xice.c_str(), xgoogle_xice.length(),
                              &offer_str);
   JsepSessionDescription *ice_only_offer =
@@ -2396,9 +2748,9 @@ TEST_F(WebRtcSessionTest, TestIceOfferGIceOnlyAnswer) {
 TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   SetLocalDescriptionWithoutError(offer);
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateRemoteAnswer(session_->local_description()));
 
   cricket::SessionDescription* answer_copy = answer->description()->Copy();
@@ -2411,22 +2763,31 @@ TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
                                           answer->session_version()));
   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
 
-  // Modifying content names.
+  // Different content names.
   std::string sdp;
   EXPECT_TRUE(answer->ToString(&sdp));
   const std::string kAudioMid = "a=mid:audio";
   const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
-
-  // Replacing |audio| with |audio_content_name|.
-  talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
+  rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
                              kAudioMidReplaceStr.c_str(),
                              kAudioMidReplaceStr.length(),
                              &sdp);
-
   SessionDescriptionInterface* modified_answer1 =
       CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
   SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
 
+  // Different media types.
+  EXPECT_TRUE(answer->ToString(&sdp));
+  const std::string kAudioMline = "m=audio";
+  const std::string kAudioMlineReplaceStr = "m=video";
+  rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
+                             kAudioMlineReplaceStr.c_str(),
+                             kAudioMlineReplaceStr.length(),
+                             &sdp);
+  SessionDescriptionInterface* modified_answer2 =
+      CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
+  SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
+
   SetRemoteDescriptionWithoutError(answer.release());
 }
 
@@ -2472,7 +2833,7 @@ TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
   ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
 
   // Pump for 1 second and verify that no candidates are generated.
-  talk_base::Thread::Current()->ProcessMessages(1000);
+  rtc::Thread::Current()->ProcessMessages(1000);
   EXPECT_TRUE(observer_.mline_0_candidates_.empty());
   EXPECT_TRUE(observer_.mline_1_candidates_.empty());
 
@@ -2488,8 +2849,7 @@ TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
 TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
 
   // Making sure SetLocalDescription correctly sets crypto value in
   // SessionDescription object after de-serialization of sdp string. The value
@@ -2508,8 +2868,7 @@ TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
   options_.disable_encryption = true;
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(
-      CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
 
   // Making sure SetLocalDescription correctly sets crypto value in
   // SessionDescription object after de-serialization of sdp string. The value
@@ -2530,22 +2889,22 @@ TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
   cricket::MediaSessionOptions options;
   options.has_audio = true;
   options.has_video = true;
-  talk_base::scoped_ptr<JsepSessionDescription> offer(
+  rtc::scoped_ptr<JsepSessionDescription> offer(
       CreateRemoteOffer(options));
   SetRemoteDescriptionWithoutError(offer.release());
 
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer with new ufrag and password.
   options.transport_options.ice_restart = true;
-  talk_base::scoped_ptr<JsepSessionDescription> updated_offer1(
+  rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
       CreateRemoteOffer(options, session_->remote_description()));
   SetRemoteDescriptionWithoutError(updated_offer1.release());
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer1(
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
       CreateAnswer(NULL));
 
   CompareIceUfragAndPassword(updated_answer1->description(),
@@ -2562,22 +2921,22 @@ TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
   cricket::MediaSessionOptions options;
   options.has_audio = true;
   options.has_video = true;
-  talk_base::scoped_ptr<JsepSessionDescription> offer(
+  rtc::scoped_ptr<JsepSessionDescription> offer(
       CreateRemoteOffer(options));
   SetRemoteDescriptionWithoutError(offer.release());
 
   mediastream_signaling_.SendAudioVideoStream1();
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(
       CreateAnswer(NULL));
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer without changed ufrag or password.
   options.transport_options.ice_restart = false;
-  talk_base::scoped_ptr<JsepSessionDescription> updated_offer2(
+  rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
       CreateRemoteOffer(options, session_->remote_description()));
   SetRemoteDescriptionWithoutError(updated_offer2.release());
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer2(
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
       CreateAnswer(NULL));
 
   CompareIceUfragAndPassword(updated_answer2->description(),
@@ -2590,7 +2949,7 @@ TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
 TEST_F(WebRtcSessionTest, TestSessionContentError) {
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
   const std::string session_id_orig = offer->session_id();
   const std::string session_version_orig = offer->session_version();
   SetLocalDescriptionWithoutError(offer);
@@ -2607,17 +2966,18 @@ TEST_F(WebRtcSessionTest, TestSessionContentError) {
 // Runs the loopback call test with BUNDLE and STUN disabled.
 TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
   // Lets try with only UDP ports.
-  allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+  allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
                        cricket::PORTALLOCATOR_DISABLE_TCP |
                        cricket::PORTALLOCATOR_DISABLE_STUN |
                        cricket::PORTALLOCATOR_DISABLE_RELAY);
   TestLoopbackCall();
 }
 
-// Runs the loopback call test with BUNDLE, STUN, and TCP enabled.
+// Runs the loopback call test with BUNDLE and STUN enabled.
 TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
-  allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+  allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
                        cricket::PORTALLOCATOR_ENABLE_BUNDLE |
+                       cricket::PORTALLOCATOR_DISABLE_TCP |
                        cricket::PORTALLOCATOR_DISABLE_RELAY);
   TestLoopbackCall();
 }
@@ -2656,43 +3016,43 @@ TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
 }
 
 TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
 
   constraints_.reset(new FakeConstraints());
   constraints_->AddOptional(
       webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
   options_.disable_sctp_data_channels = false;
 
-  InitWithDtls(false);
+  InitWithDtls();
 
   SetLocalDescriptionWithDataChannel();
   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
 }
 
 TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
 
-  InitWithDtls(false);
+  InitWithDtls();
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
   EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
 }
 
 TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   SetFactoryDtlsSrtp();
-  InitWithDtls(false);
+  InitWithDtls();
 
   // Create remote offer with SCTP.
   cricket::MediaSessionOptions options;
   options.data_channel_type = cricket::DCT_SCTP;
   JsepSessionDescription* offer =
-      CreateRemoteOffer(options, cricket::SEC_ENABLED);
+      CreateRemoteOffer(options, cricket::SEC_DISABLED);
   SetRemoteDescriptionWithoutError(offer);
 
   // Verifies the answer contains SCTP.
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   EXPECT_TRUE(answer != NULL);
   EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
   EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
@@ -2702,36 +3062,36 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
   constraints_.reset(new FakeConstraints());
   constraints_->AddOptional(
       webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
-  InitWithDtls(false);
+  InitWithDtls();
 
   SetLocalDescriptionWithDataChannel();
   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
 }
 
 TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
 
-  InitWithDtls(false);
+  InitWithDtls();
 
   SetLocalDescriptionWithDataChannel();
   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
 }
 
 TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   options_.disable_sctp_data_channels = true;
-  InitWithDtls(false);
+  InitWithDtls();
 
   SetLocalDescriptionWithDataChannel();
   EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
 }
 
 TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   const int new_send_port = 9998;
   const int new_recv_port = 7775;
 
-  InitWithDtls(false);
+  InitWithDtls();
   SetFactoryDtlsSrtp();
 
   // By default, don't actually add the codecs to desc_factory_; they don't
@@ -2757,7 +3117,7 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
   webrtc::InternalDataChannelInit dci;
   dci.reliable = true;
   EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
-  talk_base::scoped_refptr<webrtc::DataChannel> dc =
+  rtc::scoped_refptr<webrtc::DataChannel> dc =
       session_->CreateDataChannel("datachannel", &dci);
 
   cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
@@ -2783,49 +3143,59 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
 // Verifies that CreateOffer succeeds when CreateOffer is called before async
 // identity generation is finished.
 TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
-  InitWithDtls(false);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
 
   EXPECT_TRUE(session_->waiting_for_identity());
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
+  mediastream_signaling_.SendAudioVideoStream1();
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
+
   EXPECT_TRUE(offer != NULL);
+  VerifyNoCryptoParams(offer->description(), true);
+  VerifyFingerprintStatus(offer->description(), true);
 }
 
 // Verifies that CreateAnswer succeeds when CreateOffer is called before async
 // identity generation is finished.
 TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
-  InitWithDtls(false);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
+  SetFactoryDtlsSrtp();
 
   cricket::MediaSessionOptions options;
+  options.has_video = true;
   scoped_ptr<JsepSessionDescription> offer(
-        CreateRemoteOffer(options, cricket::SEC_REQUIRED));
+        CreateRemoteOffer(options, cricket::SEC_DISABLED));
   ASSERT_TRUE(offer.get() != NULL);
   SetRemoteDescriptionWithoutError(offer.release());
 
-  talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
   EXPECT_TRUE(answer != NULL);
+  VerifyNoCryptoParams(answer->description(), true);
+  VerifyFingerprintStatus(answer->description(), true);
 }
 
 // Verifies that CreateOffer succeeds when CreateOffer is called after async
 // identity generation is finished.
 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
-  InitWithDtls(false);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
 
   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   EXPECT_TRUE(offer != NULL);
 }
 
 // Verifies that CreateOffer fails when CreateOffer is called after async
 // identity generation fails.
 TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtls(true);
 
   EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
-  talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
+
+  rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   EXPECT_TRUE(offer == NULL);
 }
 
@@ -2833,7 +3203,7 @@ TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
 // before async identity generation is finished.
 TEST_F(WebRtcSessionTest,
        TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   VerifyMultipleAsyncCreateDescription(
       true, CreateSessionDescriptionRequest::kOffer);
 }
@@ -2842,7 +3212,7 @@ TEST_F(WebRtcSessionTest,
 // before async identity generation fails.
 TEST_F(WebRtcSessionTest,
        TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   VerifyMultipleAsyncCreateDescription(
       false, CreateSessionDescriptionRequest::kOffer);
 }
@@ -2851,7 +3221,7 @@ TEST_F(WebRtcSessionTest,
 // before async identity generation is finished.
 TEST_F(WebRtcSessionTest,
        TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   VerifyMultipleAsyncCreateDescription(
       true, CreateSessionDescriptionRequest::kAnswer);
 }
@@ -2860,7 +3230,7 @@ TEST_F(WebRtcSessionTest,
 // before async identity generation fails.
 TEST_F(WebRtcSessionTest,
        TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
-  MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   VerifyMultipleAsyncCreateDescription(
       false, CreateSessionDescriptionRequest::kAnswer);
 }
@@ -2880,9 +3250,9 @@ TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
   ASSERT_TRUE(audio != NULL);
   ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
   audio->description.identity_fingerprint.reset(
-      talk_base::SSLFingerprint::CreateFromRfc4572(
-          talk_base::DIGEST_SHA_256, kFakeDtlsFingerprint));
-  SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesAndDtlsDisabled,
+      rtc::SSLFingerprint::CreateFromRfc4572(
+          rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
+  SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
                                        offer);
 }
 
@@ -2893,7 +3263,7 @@ TEST_F(WebRtcSessionTest, TestDscpConstraint) {
       webrtc::MediaConstraintsInterface::kEnableDscp, true);
   Init(NULL);
   mediastream_signaling_.SendAudioVideoStream1();
-  SessionDescriptionInterface* offer = CreateOffer(NULL);
+  SessionDescriptionInterface* offer = CreateOffer();
 
   SetLocalDescriptionWithoutError(offer);
 
@@ -2912,6 +3282,95 @@ TEST_F(WebRtcSessionTest, TestDscpConstraint) {
   EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
 }
 
+TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
+  constraints_.reset(new FakeConstraints());
+  constraints_->AddOptional(
+      webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
+      true);
+  Init(NULL);
+  mediastream_signaling_.SendAudioVideoStream1();
+  SessionDescriptionInterface* offer = CreateOffer();
+
+  SetLocalDescriptionWithoutError(offer);
+
+  video_channel_ = media_engine_->GetVideoChannel(0);
+
+  ASSERT_TRUE(video_channel_ != NULL);
+  cricket::VideoOptions video_options;
+  EXPECT_TRUE(video_channel_->GetOptions(&video_options));
+  EXPECT_TRUE(
+      video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
+}
+
+TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
+  // Number of unsignalled receiving streams should be between 0 and
+  // kMaxUnsignalledRecvStreams.
+  SetAndVerifyNumUnsignalledRecvStreams(10, 10);
+  SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
+                                        kMaxUnsignalledRecvStreams);
+  SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
+}
+
+// Tests that we can renegotiate new media content with ICE candidates in the
+// new remote SDP.
+TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
+  SetFactoryDtlsSrtp();
+
+  mediastream_signaling_.UseOptionsAudioOnly();
+  SessionDescriptionInterface* offer = CreateOffer();
+  SetLocalDescriptionWithoutError(offer);
+
+  SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
+  SetRemoteDescriptionWithoutError(answer);
+
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
+
+  cricket::Candidate candidate1;
+  candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
+  candidate1.set_component(1);
+  JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
+                                 candidate1);
+  EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
+  SetRemoteDescriptionWithoutError(offer);
+
+  answer = CreateAnswer(NULL);
+  SetLocalDescriptionWithoutError(answer);
+}
+
+// Tests that we can renegotiate new media content with ICE candidates separated
+// from the remote SDP.
+TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
+  MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
+  InitWithDtls();
+  SetFactoryDtlsSrtp();
+
+  mediastream_signaling_.UseOptionsAudioOnly();
+  SessionDescriptionInterface* offer = CreateOffer();
+  SetLocalDescriptionWithoutError(offer);
+
+  SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
+  SetRemoteDescriptionWithoutError(answer);
+
+  cricket::MediaSessionOptions options;
+  options.has_video = true;
+  offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
+  SetRemoteDescriptionWithoutError(offer);
+
+  cricket::Candidate candidate1;
+  candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
+  candidate1.set_component(1);
+  JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
+                                 candidate1);
+  EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
+
+  answer = CreateAnswer(NULL);
+  SetLocalDescriptionWithoutError(answer);
+}
+
 // TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled.  That test
 // currently fails because upon disconnection and reconnection OnIceComplete is
 // called more than once without returning to IceGatheringGathering.