This CL provides interfaces that do not use constraints for
all interfaces that formerly took constraints parameters
in name=value form.

This is in preparation for making Chrome only use these
explicit interfaces.

BUG=webrtc:4906

Review URL: https://codereview.webrtc.org/1717583002

Cr-Commit-Position: refs/heads/master@{#11870}
diff --git a/webrtc/api/api_tests.gyp b/webrtc/api/api_tests.gyp
index ada036a..814784f 100644
--- a/webrtc/api/api_tests.gyp
+++ b/webrtc/api/api_tests.gyp
@@ -37,6 +37,7 @@
         'fakemetricsobserver.h',
         'jsepsessiondescription_unittest.cc',
         'localaudiosource_unittest.cc',
+	'mediaconstraintsinterface_unittest.cc',
         'mediastream_unittest.cc',
         'peerconnection_unittest.cc',
         'peerconnectionendtoend_unittest.cc',
diff --git a/webrtc/api/localaudiosource.cc b/webrtc/api/localaudiosource.cc
index a118655..3b22ad1 100644
--- a/webrtc/api/localaudiosource.cc
+++ b/webrtc/api/localaudiosource.cc
@@ -76,6 +76,15 @@
   return source;
 }
 
+rtc::scoped_refptr<LocalAudioSource> LocalAudioSource::Create(
+    const PeerConnectionFactoryInterface::Options& options,
+    const cricket::AudioOptions* audio_options) {
+  rtc::scoped_refptr<LocalAudioSource> source(
+      new rtc::RefCountedObject<LocalAudioSource>());
+  source->Initialize(options, audio_options);
+  return source;
+}
+
 void LocalAudioSource::Initialize(
     const PeerConnectionFactoryInterface::Options& options,
     const MediaConstraintsInterface* constraints) {
@@ -89,7 +98,15 @@
   cricket::AudioOptions mandatory_options;
   FromConstraints(constraints->GetMandatory(), &mandatory_options);
   options_.SetAll(mandatory_options);
-  source_state_ = kLive;
+}
+
+void LocalAudioSource::Initialize(
+    const PeerConnectionFactoryInterface::Options& options,
+    const cricket::AudioOptions* audio_options) {
+  if (!audio_options)
+    return;
+
+  options_ = *audio_options;
 }
 
 }  // namespace webrtc
diff --git a/webrtc/api/localaudiosource.h b/webrtc/api/localaudiosource.h
index d463d1c..e4de650 100644
--- a/webrtc/api/localaudiosource.h
+++ b/webrtc/api/localaudiosource.h
@@ -31,7 +31,11 @@
       const PeerConnectionFactoryInterface::Options& options,
       const MediaConstraintsInterface* constraints);
 
-  SourceState state() const override { return source_state_; }
+  static rtc::scoped_refptr<LocalAudioSource> Create(
+      const PeerConnectionFactoryInterface::Options& options,
+      const cricket::AudioOptions* audio_options);
+
+  SourceState state() const override { return kLive; }
   bool remote() const override { return false; }
 
   virtual const cricket::AudioOptions& options() const { return options_; }
@@ -40,15 +44,16 @@
   void RemoveSink(AudioTrackSinkInterface* sink) override {}
 
  protected:
-  LocalAudioSource() : source_state_(kInitializing) {}
+  LocalAudioSource() {}
   ~LocalAudioSource() override {}
 
  private:
   void Initialize(const PeerConnectionFactoryInterface::Options& options,
                   const MediaConstraintsInterface* constraints);
+  void Initialize(const PeerConnectionFactoryInterface::Options& options,
+                  const cricket::AudioOptions* audio_options);
 
   cricket::AudioOptions options_;
-  SourceState source_state_;
 };
 
 }  // namespace webrtc
diff --git a/webrtc/api/localaudiosource_unittest.cc b/webrtc/api/localaudiosource_unittest.cc
index 1abb940..12f46b7 100644
--- a/webrtc/api/localaudiosource_unittest.cc
+++ b/webrtc/api/localaudiosource_unittest.cc
@@ -96,3 +96,18 @@
   EXPECT_EQ(MediaSourceInterface::kLive, source->state());
   EXPECT_EQ(rtc::Optional<bool>(false), source->options().highpass_filter);
 }
+
+TEST(LocalAudioSourceTest, InitWithAudioOptions) {
+  cricket::AudioOptions audio_options;
+  audio_options.highpass_filter = rtc::Optional<bool>(true);
+  rtc::scoped_refptr<LocalAudioSource> source = LocalAudioSource::Create(
+      PeerConnectionFactoryInterface::Options(), &audio_options);
+  EXPECT_EQ(rtc::Optional<bool>(true), source->options().highpass_filter);
+}
+
+TEST(LocalAudioSourceTest, InitWithNoOptions) {
+  rtc::scoped_refptr<LocalAudioSource> source =
+      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
+                               (cricket::AudioOptions*)nullptr);
+  EXPECT_EQ(rtc::Optional<bool>(), source->options().highpass_filter);
+}
diff --git a/webrtc/api/mediaconstraintsinterface.cc b/webrtc/api/mediaconstraintsinterface.cc
index b0a68b1..af25891 100644
--- a/webrtc/api/mediaconstraintsinterface.cc
+++ b/webrtc/api/mediaconstraintsinterface.cc
@@ -10,6 +10,7 @@
 
 #include "webrtc/api/mediaconstraintsinterface.h"
 
+#include "webrtc/api/peerconnectioninterface.h"
 #include "webrtc/base/stringencode.h"
 
 namespace webrtc {
@@ -118,8 +119,9 @@
     return false;
   }
   if (constraints->GetMandatory().FindFirst(key, &string_value)) {
-    if (mandatory_constraints)
+    if (mandatory_constraints) {
       ++*mandatory_constraints;
+    }
     return rtc::FromString(string_value, value);
   }
   if (constraints->GetOptional().FindFirst(key, &string_value)) {
@@ -128,4 +130,87 @@
   return false;
 }
 
+// As above, but for integers.
+bool FindConstraint(const MediaConstraintsInterface* constraints,
+                    const std::string& key,
+                    int* value,
+                    size_t* mandatory_constraints) {
+  std::string string_value;
+  if (!constraints) {
+    return false;
+  }
+  if (constraints->GetMandatory().FindFirst(key, &string_value)) {
+    if (mandatory_constraints) {
+      ++*mandatory_constraints;
+    }
+    return rtc::FromString(string_value, value);
+  }
+  if (constraints->GetOptional().FindFirst(key, &string_value)) {
+    return rtc::FromString(string_value, value);
+  }
+  return false;
+}
+
+void ConstraintToOptionalBool(const MediaConstraintsInterface* constraints,
+                              const std::string& key,
+                              rtc::Optional<bool>* value_out) {
+  bool value;
+  bool present = FindConstraint(constraints, key, &value, nullptr);
+  if (present) {
+    *value_out = rtc::Optional<bool>(value);
+  }
+}
+
+void ConstraintToOptionalInt(const MediaConstraintsInterface* constraints,
+                             const std::string& key,
+                             rtc::Optional<int>* value_out) {
+  int value;
+  bool present = FindConstraint(constraints, key, &value, nullptr);
+  if (present) {
+    *value_out = rtc::Optional<int>(value);
+  }
+}
+
+void CopyConstraintsIntoRtcConfiguration(
+    const MediaConstraintsInterface* constraints,
+    PeerConnectionInterface::RTCConfiguration* configuration) {
+  // Copy info from constraints into configuration, if present.
+  if (!constraints) {
+    return;
+  }
+
+  bool value;
+  if (FindConstraint(constraints, MediaConstraintsInterface::kEnableIPv6,
+                     &value, nullptr)) {
+    if (!value) {
+      configuration->disable_ipv6 = true;
+    }
+  }
+  ConstraintToOptionalBool(constraints, MediaConstraintsInterface::kEnableDscp,
+                           &configuration->enable_dscp);
+  ConstraintToOptionalBool(constraints,
+                           MediaConstraintsInterface::kCpuOveruseDetection,
+                           &configuration->cpu_overuse_detection);
+  if (FindConstraint(constraints,
+                     MediaConstraintsInterface::kEnableRtpDataChannels, &value,
+                     NULL) &&
+      value) {
+    configuration->enable_rtp_data_channel = true;
+  }
+  // Find Suspend Below Min Bitrate constraint.
+  ConstraintToOptionalBool(
+      constraints,
+      MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
+      &configuration->suspend_below_min_bitrate);
+  ConstraintToOptionalInt(constraints,
+                          MediaConstraintsInterface::kScreencastMinBitrate,
+                          &configuration->screencast_min_bitrate);
+  ConstraintToOptionalBool(constraints,
+                           MediaConstraintsInterface::kCombinedAudioVideoBwe,
+                           &configuration->combined_audio_video_bwe);
+  ConstraintToOptionalBool(constraints,
+                           MediaConstraintsInterface::kEnableDtlsSrtp,
+                           &configuration->enable_dtls_srtp);
+}
+
 }  // namespace webrtc
diff --git a/webrtc/api/mediaconstraintsinterface.h b/webrtc/api/mediaconstraintsinterface.h
index 0c251f8..3db6e26 100644
--- a/webrtc/api/mediaconstraintsinterface.h
+++ b/webrtc/api/mediaconstraintsinterface.h
@@ -13,12 +13,19 @@
 // http://www.w3.org/TR/mediacapture-streams/#mediastreamconstraints and also
 // used in WebRTC: http://dev.w3.org/2011/webrtc/editor/webrtc.html#constraints.
 
+// This interface is being deprecated in Chrome, and may be removed
+// from WebRTC too.
+// https://bugs.chromium.org/p/webrtc/issues/detail?id=5617
+
 #ifndef WEBRTC_API_MEDIACONSTRAINTSINTERFACE_H_
 #define WEBRTC_API_MEDIACONSTRAINTSINTERFACE_H_
 
 #include <string>
 #include <vector>
 
+#include "webrtc/base/optional.h"
+#include "webrtc/api/peerconnectioninterface.h"
+
 namespace webrtc {
 
 // MediaConstraintsInterface
@@ -118,6 +125,16 @@
                     const std::string& key, bool* value,
                     size_t* mandatory_constraints);
 
+bool FindConstraint(const MediaConstraintsInterface* constraints,
+                    const std::string& key,
+                    int* value,
+                    size_t* mandatory_constraints);
+
+// Copy all relevant constraints into an RTCConfiguration object.
+void CopyConstraintsIntoRtcConfiguration(
+    const MediaConstraintsInterface* constraints,
+    PeerConnectionInterface::RTCConfiguration* configuration);
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_API_MEDIACONSTRAINTSINTERFACE_H_
diff --git a/webrtc/api/mediaconstraintsinterface_unittest.cc b/webrtc/api/mediaconstraintsinterface_unittest.cc
new file mode 100644
index 0000000..07338c1
--- /dev/null
+++ b/webrtc/api/mediaconstraintsinterface_unittest.cc
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/api/mediaconstraintsinterface.h"
+
+#include "webrtc/api/test/fakeconstraints.h"
+#include "webrtc/base/gunit.h"
+
+namespace webrtc {
+
+namespace {
+
+bool Matches(const PeerConnectionInterface::RTCConfiguration& a,
+             const PeerConnectionInterface::RTCConfiguration& b) {
+  return a.audio_jitter_buffer_max_packets ==
+             b.audio_jitter_buffer_max_packets &&
+         a.disable_prerenderer_smoothing == b.disable_prerenderer_smoothing;
+}
+
+TEST(MediaConstraintsInterface, CopyConstraintsIntoRtcConfiguration) {
+  FakeConstraints constraints;
+  PeerConnectionInterface::RTCConfiguration old_configuration;
+  PeerConnectionInterface::RTCConfiguration configuration;
+
+  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  EXPECT_TRUE(Matches(old_configuration, configuration));
+
+  constraints.SetMandatory(MediaConstraintsInterface::kEnableIPv6, "true");
+  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  EXPECT_FALSE(configuration.disable_ipv6);
+  constraints.SetMandatory(MediaConstraintsInterface::kEnableIPv6, "false");
+  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  EXPECT_TRUE(configuration.disable_ipv6);
+
+  constraints.SetMandatory(MediaConstraintsInterface::kScreencastMinBitrate,
+                           27);
+  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  EXPECT_TRUE(configuration.screencast_min_bitrate);
+  EXPECT_EQ(27, *(configuration.screencast_min_bitrate));
+
+  // An empty set of constraints will not overwrite
+  // values that are already present.
+  constraints = FakeConstraints();
+  configuration = old_configuration;
+  configuration.enable_dtls_srtp = rtc::Optional<bool>(true);
+  configuration.audio_jitter_buffer_max_packets = 34;
+  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  EXPECT_EQ(34, configuration.audio_jitter_buffer_max_packets);
+  ASSERT_TRUE(configuration.enable_dtls_srtp);
+  EXPECT_TRUE(*(configuration.enable_dtls_srtp));
+}
+
+}  // namespace
+
+}  // namespace webrtc
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index 1eca42a..6ea852d 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -427,7 +427,7 @@
   rtc::Thread* worker_thread_;
 };
 
-bool ConvertRtcOptionsForOffer(
+bool ExtractMediaSessionOptions(
     const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
     cricket::MediaSessionOptions* session_options) {
   typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
@@ -565,8 +565,8 @@
 }
 
 bool PeerConnection::Initialize(
+    const cricket::MediaConfig& media_config,
     const PeerConnectionInterface::RTCConfiguration& configuration,
-    const MediaConstraintsInterface* constraints,
     rtc::scoped_ptr<cricket::PortAllocator> allocator,
     rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
     PeerConnectionObserver* observer) {
@@ -591,13 +591,10 @@
   int portallocator_flags = port_allocator_->flags();
   portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
                          cricket::PORTALLOCATOR_ENABLE_IPV6;
-  bool value;
-  // If IPv6 flag was specified, we'll not override it by experiment.
-  if (FindConstraint(constraints, MediaConstraintsInterface::kEnableIPv6,
-                     &value, nullptr)) {
-    if (!value) {
-      portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
-    }
+  // If the disable-IPv6 flag was specified, we'll not override it
+  // by experiment.
+  if (configuration.disable_ipv6) {
+    portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
   } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") ==
              "Disabled") {
     portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
@@ -612,24 +609,6 @@
   // No step delay is used while allocating ports.
   port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
 
-  // We rely on default values when constraints aren't found.
-  cricket::MediaConfig media_config;
-
-  media_config.video.disable_prerenderer_smoothing =
-      configuration.disable_prerenderer_smoothing;
-
-  // Find DSCP constraint.
-  FindConstraint(constraints, MediaConstraintsInterface::kEnableDscp,
-                 &media_config.enable_dscp, NULL);
-  // Find constraint for cpu overuse detection.
-  FindConstraint(constraints, MediaConstraintsInterface::kCpuOveruseDetection,
-                 &media_config.video.enable_cpu_overuse_detection, NULL);
-
-  // Find Suspend Below Min Bitrate constraint.
-  FindConstraint(constraints,
-                 MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
-                 &media_config.video.suspend_below_min_bitrate, NULL);
-
   media_controller_.reset(factory_->CreateMediaController(media_config));
 
   remote_stream_factory_.reset(new RemoteMediaStreamFactory(
@@ -641,8 +620,8 @@
   stats_.reset(new StatsCollector(this));
 
   // Initialize the WebRtcSession. It creates transport channels etc.
-  if (!session_->Initialize(factory_->options(), constraints,
-                            std::move(dtls_identity_store), configuration)) {
+  if (!session_->Initialize(factory_->options(), std::move(dtls_identity_store),
+                            configuration)) {
     return false;
   }
 
@@ -1006,7 +985,26 @@
     return;
   }
 
-  session_->CreateAnswer(observer, constraints, session_options);
+  session_->CreateAnswer(observer, session_options);
+}
+
+void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
+                                  const RTCOfferAnswerOptions& options) {
+  TRACE_EVENT0("webrtc", "PeerConnection::CreateAnswer");
+  if (!VERIFY(observer != nullptr)) {
+    LOG(LS_ERROR) << "CreateAnswer - observer is NULL.";
+    return;
+  }
+
+  cricket::MediaSessionOptions session_options;
+  if (!GetOptionsForAnswer(options, &session_options)) {
+    std::string error = "CreateAnswer called with invalid options.";
+    LOG(LS_ERROR) << error;
+    PostCreateSessionDescriptionFailure(observer, error);
+    return;
+  }
+
+  session_->CreateAnswer(observer, session_options);
 }
 
 void PeerConnection::SetLocalDescription(
@@ -1510,7 +1508,7 @@
           cricket::TransportOptions();
     }
   }
-  if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) {
+  if (!ExtractMediaSessionOptions(rtc_options, session_options)) {
     return false;
   }
 
@@ -1538,11 +1536,8 @@
   return true;
 }
 
-bool PeerConnection::GetOptionsForAnswer(
-    const MediaConstraintsInterface* constraints,
+void PeerConnection::FinishOptionsForAnswer(
     cricket::MediaSessionOptions* session_options) {
-  session_options->recv_audio = false;
-  session_options->recv_video = false;
   // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
   // ContentInfos.
   if (session_->remote_description()) {
@@ -1553,10 +1548,6 @@
           cricket::TransportOptions();
     }
   }
-  if (!ParseConstraintsForAnswer(constraints, session_options)) {
-    return false;
-  }
-
   AddSendStreams(session_options, senders_, rtp_data_channels_);
   session_options->bundle_enabled =
       session_options->bundle_enabled &&
@@ -1569,6 +1560,29 @@
   if (session_->data_channel_type() == cricket::DCT_SCTP) {
     session_options->data_channel_type = cricket::DCT_SCTP;
   }
+}
+
+bool PeerConnection::GetOptionsForAnswer(
+    const MediaConstraintsInterface* constraints,
+    cricket::MediaSessionOptions* session_options) {
+  session_options->recv_audio = false;
+  session_options->recv_video = false;
+  if (!ParseConstraintsForAnswer(constraints, session_options)) {
+    return false;
+  }
+  FinishOptionsForAnswer(session_options);
+  return true;
+}
+
+bool PeerConnection::GetOptionsForAnswer(
+    const RTCOfferAnswerOptions& options,
+    cricket::MediaSessionOptions* session_options) {
+  session_options->recv_audio = false;
+  session_options->recv_video = false;
+  if (!ExtractMediaSessionOptions(options, session_options)) {
+    return false;
+  }
+  FinishOptionsForAnswer(session_options);
   return true;
 }
 
diff --git a/webrtc/api/peerconnection.h b/webrtc/api/peerconnection.h
index a63dd43..e4fcdf0 100644
--- a/webrtc/api/peerconnection.h
+++ b/webrtc/api/peerconnection.h
@@ -32,13 +32,20 @@
 // are valid.
 // |session_options|->transport_options map entries must exist in order for
 // them to be populated from |rtc_options|.
-bool ConvertRtcOptionsForOffer(
+bool ExtractMediaSessionOptions(
     const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
     cricket::MediaSessionOptions* session_options);
 
 // Populates |session_options| from |constraints|, and returns true if all
 // mandatory constraints are satisfied.
 // Assumes that |session_options|->transport_options map entries exist.
+// Will also set defaults if corresponding constraints are not present:
+// recv_audio=true, recv_video=true, bundle_enabled=true.
+// Other fields will be left with existing values.
+//
+// Deprecated. Will be removed once callers that use constraints are gone.
+// TODO(hta): Remove when callers are gone.
+// https://bugs.chromium.org/p/webrtc/issues/detail?id=5617
 bool ParseConstraintsForAnswer(const MediaConstraintsInterface* constraints,
                                cricket::MediaSessionOptions* session_options);
 
@@ -58,8 +65,8 @@
   explicit PeerConnection(PeerConnectionFactory* factory);
 
   bool Initialize(
+      const cricket::MediaConfig& media_config,
       const PeerConnectionInterface::RTCConfiguration& configuration,
-      const MediaConstraintsInterface* constraints,
       rtc::scoped_ptr<cricket::PortAllocator> allocator,
       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
       PeerConnectionObserver* observer);
@@ -106,12 +113,16 @@
   const SessionDescriptionInterface* remote_description() const override;
 
   // JSEP01
+  // Deprecated, use version without constraints.
   void CreateOffer(CreateSessionDescriptionObserver* observer,
                    const MediaConstraintsInterface* constraints) override;
   void CreateOffer(CreateSessionDescriptionObserver* observer,
                    const RTCOfferAnswerOptions& options) override;
+  // Deprecated, use version without constraints.
   void CreateAnswer(CreateSessionDescriptionObserver* observer,
                     const MediaConstraintsInterface* constraints) override;
+  void CreateAnswer(CreateSessionDescriptionObserver* observer,
+                    const RTCOfferAnswerOptions& options) override;
   void SetLocalDescription(SetSessionDescriptionObserver* observer,
                            SessionDescriptionInterface* desc) override;
   void SetRemoteDescription(SetSessionDescriptionObserver* observer,
@@ -211,9 +222,18 @@
 
   // Returns a MediaSessionOptions struct with options decided by
   // |constraints|, the local MediaStreams and DataChannels.
+  // Deprecated, use version without constraints.
   virtual bool GetOptionsForAnswer(
       const MediaConstraintsInterface* constraints,
       cricket::MediaSessionOptions* session_options);
+  virtual bool GetOptionsForAnswer(
+      const RTCOfferAnswerOptions& options,
+      cricket::MediaSessionOptions* session_options);
+
+  // Helper function for options processing.
+  // Deprecated.
+  virtual void FinishOptionsForAnswer(
+      cricket::MediaSessionOptions* session_options);
 
   // Remove all local and remote tracks of type |media_type|.
   // Called when a media type is rejected (m-line set to port 0).
diff --git a/webrtc/api/peerconnectionfactory.cc b/webrtc/api/peerconnectionfactory.cc
index d63045f..4d8125f 100644
--- a/webrtc/api/peerconnectionfactory.cc
+++ b/webrtc/api/peerconnectionfactory.cc
@@ -14,6 +14,7 @@
 
 #include "webrtc/api/audiotrack.h"
 #include "webrtc/api/localaudiosource.h"
+#include "webrtc/api/mediaconstraintsinterface.h"
 #include "webrtc/api/mediastream.h"
 #include "webrtc/api/mediastreamproxy.h"
 #include "webrtc/api/mediastreamtrackproxy.h"
@@ -199,6 +200,14 @@
   return source;
 }
 
+rtc::scoped_refptr<AudioSourceInterface>
+PeerConnectionFactory::CreateAudioSource(const cricket::AudioOptions& options) {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  rtc::scoped_refptr<LocalAudioSource> source(
+      LocalAudioSource::Create(options_, &options));
+  return source;
+}
+
 rtc::scoped_refptr<VideoSourceInterface>
 PeerConnectionFactory::CreateVideoSource(
     cricket::VideoCapturer* capturer,
@@ -209,6 +218,14 @@
   return VideoSourceProxy::Create(signaling_thread_, source);
 }
 
+rtc::scoped_refptr<VideoSourceInterface>
+PeerConnectionFactory::CreateVideoSource(cricket::VideoCapturer* capturer) {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  rtc::scoped_refptr<VideoSource> source(
+      VideoSource::Create(worker_thread_, capturer, false));
+  return VideoSourceProxy::Create(signaling_thread_, source);
+}
+
 bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file,
                                          int64_t max_size_bytes) {
   RTC_DCHECK(signaling_thread_->IsCurrent());
@@ -232,13 +249,29 @@
 
 rtc::scoped_refptr<PeerConnectionInterface>
 PeerConnectionFactory::CreatePeerConnection(
-    const PeerConnectionInterface::RTCConfiguration& configuration,
+    const PeerConnectionInterface::RTCConfiguration& configuration_in,
     const MediaConstraintsInterface* constraints,
     rtc::scoped_ptr<cricket::PortAllocator> allocator,
     rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
     PeerConnectionObserver* observer) {
   RTC_DCHECK(signaling_thread_->IsCurrent());
 
+  // We merge constraints and configuration into a single configuration.
+  PeerConnectionInterface::RTCConfiguration configuration = configuration_in;
+  CopyConstraintsIntoRtcConfiguration(constraints, &configuration);
+
+  return CreatePeerConnection(configuration, std::move(allocator),
+                              std::move(dtls_identity_store), observer);
+}
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactory::CreatePeerConnection(
+    const PeerConnectionInterface::RTCConfiguration& configuration,
+    rtc::scoped_ptr<cricket::PortAllocator> allocator,
+    rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
+    PeerConnectionObserver* observer) {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+
   if (!dtls_identity_store.get()) {
     // Because |pc|->Initialize takes ownership of the store we need a new
     // wrapper object that can be deleted without deleting the underlying
@@ -255,7 +288,24 @@
 
   rtc::scoped_refptr<PeerConnection> pc(
       new rtc::RefCountedObject<PeerConnection>(this));
-  if (!pc->Initialize(configuration, constraints, std::move(allocator),
+  // We rely on default values when constraints aren't found.
+  cricket::MediaConfig media_config;
+
+  media_config.video.disable_prerenderer_smoothing =
+      configuration.disable_prerenderer_smoothing;
+  if (configuration.enable_dscp) {
+    media_config.enable_dscp = *(configuration.enable_dscp);
+  }
+  if (configuration.cpu_overuse_detection) {
+    media_config.video.enable_cpu_overuse_detection =
+        *(configuration.cpu_overuse_detection);
+  }
+  if (configuration.suspend_below_min_bitrate) {
+    media_config.video.suspend_below_min_bitrate =
+        *(configuration.suspend_below_min_bitrate);
+  }
+
+  if (!pc->Initialize(media_config, configuration, std::move(allocator),
                       std::move(dtls_identity_store), observer)) {
     return nullptr;
   }
diff --git a/webrtc/api/peerconnectionfactory.h b/webrtc/api/peerconnectionfactory.h
index 3ba4124..1bc40ed 100644
--- a/webrtc/api/peerconnectionfactory.h
+++ b/webrtc/api/peerconnectionfactory.h
@@ -38,6 +38,7 @@
     options_ = options;
   }
 
+  // Deprecated, use version without constraints.
   rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
       const PeerConnectionInterface::RTCConfiguration& configuration,
       const MediaConstraintsInterface* constraints,
@@ -45,14 +46,29 @@
       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
       PeerConnectionObserver* observer) override;
 
+  virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
+      const PeerConnectionInterface::RTCConfiguration& configuration,
+      rtc::scoped_ptr<cricket::PortAllocator> allocator,
+      rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
+      PeerConnectionObserver* observer) override;
+
   bool Initialize();
 
   rtc::scoped_refptr<MediaStreamInterface>
       CreateLocalMediaStream(const std::string& label) override;
 
+  virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
+      const cricket::AudioOptions& options) override;
+  // Deprecated, use version without constraints.
   rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
       const MediaConstraintsInterface* constraints) override;
 
+  virtual rtc::scoped_refptr<VideoSourceInterface> CreateVideoSource(
+      cricket::VideoCapturer* capturer) override;
+  // This version supports filtering on width, height and frame rate.
+  // For the "constraints=null" case, use the version without constraints.
+  // TODO(hta): Design a version without MediaConstraintsInterface.
+  // https://bugs.chromium.org/p/webrtc/issues/detail?id=5617
   rtc::scoped_refptr<VideoSourceInterface> CreateVideoSource(
       cricket::VideoCapturer* capturer,
       const MediaConstraintsInterface* constraints) override;
diff --git a/webrtc/api/peerconnectionfactoryproxy.h b/webrtc/api/peerconnectionfactoryproxy.h
index a9aa91c..d83c300 100644
--- a/webrtc/api/peerconnectionfactoryproxy.h
+++ b/webrtc/api/peerconnectionfactoryproxy.h
@@ -34,13 +34,28 @@
         rtc::Bind(&PeerConnectionFactoryProxy::CreatePeerConnection_ot, this,
                   a1, a2, a3.release(), a4.release(), a5));
   }
+  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
+      const PeerConnectionInterface::RTCConfiguration& a1,
+      rtc::scoped_ptr<cricket::PortAllocator> a3,
+      rtc::scoped_ptr<DtlsIdentityStoreInterface> a4,
+      PeerConnectionObserver* a5) override {
+    return owner_thread_->Invoke<rtc::scoped_refptr<PeerConnectionInterface>>(
+        rtc::Bind(&PeerConnectionFactoryProxy::CreatePeerConnection_ot, this,
+                  a1, a3.release(), a4.release(), a5));
+  }
   PROXY_METHOD1(rtc::scoped_refptr<MediaStreamInterface>,
                 CreateLocalMediaStream, const std::string&)
   PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>,
                 CreateAudioSource, const MediaConstraintsInterface*)
+  PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>,
+                CreateAudioSource,
+                const cricket::AudioOptions&)
   PROXY_METHOD2(rtc::scoped_refptr<VideoSourceInterface>,
                 CreateVideoSource, cricket::VideoCapturer*,
                 const MediaConstraintsInterface*)
+  PROXY_METHOD1(rtc::scoped_refptr<VideoSourceInterface>,
+                CreateVideoSource,
+                cricket::VideoCapturer*)
   PROXY_METHOD2(rtc::scoped_refptr<VideoTrackInterface>,
                 CreateVideoTrack, const std::string&,  VideoSourceInterface*)
   PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>,
@@ -62,7 +77,18 @@
     return c_->CreatePeerConnection(a1, a2, std::move(ptr_a3),
                                     std::move(ptr_a4), a5);
   }
-END_PROXY()
+
+  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection_ot(
+      const PeerConnectionInterface::RTCConfiguration& a1,
+      cricket::PortAllocator* a3,
+      DtlsIdentityStoreInterface* a4,
+      PeerConnectionObserver* a5) {
+    rtc::scoped_ptr<cricket::PortAllocator> ptr_a3(a3);
+    rtc::scoped_ptr<DtlsIdentityStoreInterface> ptr_a4(a4);
+    return c_->CreatePeerConnection(a1, std::move(ptr_a3), std::move(ptr_a4),
+                                    a5);
+  }
+  END_PROXY()
 
 }  // namespace webrtc
 
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index e616122..7a83343 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -243,6 +243,17 @@
     std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
     bool disable_prerenderer_smoothing;
     bool prioritize_most_likely_ice_candidate_pairs;
+    // Flags corresponding to values set by constraint flags.
+    // rtc::Optional flags can be "missing", in which case the webrtc
+    // default applies.
+    bool disable_ipv6;
+    rtc::Optional<bool> enable_dscp;
+    bool enable_rtp_data_channel;
+    rtc::Optional<bool> cpu_overuse_detection;
+    rtc::Optional<bool> suspend_below_min_bitrate;
+    rtc::Optional<int> screencast_min_bitrate;
+    rtc::Optional<bool> combined_audio_video_bwe;
+    rtc::Optional<bool> enable_dtls_srtp;
     RTCConfiguration()
         : type(kAll),
           bundle_policy(kBundlePolicyBalanced),
@@ -254,7 +265,9 @@
           ice_backup_candidate_pair_ping_interval(kUndefined),
           continual_gathering_policy(GATHER_ONCE),
           disable_prerenderer_smoothing(false),
-          prioritize_most_likely_ice_candidate_pairs(false) {}
+          prioritize_most_likely_ice_candidate_pairs(false),
+          disable_ipv6(false),
+          enable_rtp_data_channel(false) {}
   };
 
   struct RTCOfferAnswerOptions {
@@ -382,7 +395,13 @@
   // Create an answer to an offer.
   // The CreateSessionDescriptionObserver callback will be called when done.
   virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
-                            const MediaConstraintsInterface* constraints) = 0;
+                            const RTCOfferAnswerOptions& options) {}
+  // Deprecated - use version above.
+  // TODO(hta): Remove and remove default implementations when all callers
+  // are updated.
+  virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
+                            const MediaConstraintsInterface* constraints) {}
+
   // Sets the local session description.
   // JsepInterface takes the ownership of |desc| even if it fails.
   // The |observer| callback will be called when done.
@@ -400,6 +419,7 @@
                          const MediaConstraintsInterface* constraints) {
     return false;
   }
+  virtual bool UpdateIce(const IceServers& configuration) { return false; }
   // Sets the PeerConnection's global configuration to |config|.
   // Any changes to STUN/TURN servers or ICE candidate policy will affect the
   // next gathering phase, and cause the next call to createOffer to generate
@@ -526,17 +546,31 @@
       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
       PeerConnectionObserver* observer) = 0;
 
+  virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
+      const PeerConnectionInterface::RTCConfiguration& configuration,
+      rtc::scoped_ptr<cricket::PortAllocator> allocator,
+      rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
+      PeerConnectionObserver* observer) = 0;
+
   virtual rtc::scoped_refptr<MediaStreamInterface>
       CreateLocalMediaStream(const std::string& label) = 0;
 
   // Creates a AudioSourceInterface.
   // |constraints| decides audio processing settings but can be NULL.
   virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
+      const cricket::AudioOptions& options) = 0;
+  // Deprecated - use version above.
+  virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
       const MediaConstraintsInterface* constraints) = 0;
 
   // Creates a VideoSourceInterface. The new source take ownership of
-  // |capturer|. |constraints| decides video resolution and frame rate but can
+  // |capturer|.
+  virtual rtc::scoped_refptr<VideoSourceInterface> CreateVideoSource(
+      cricket::VideoCapturer* capturer) = 0;
+  // A video source creator that allows selection of resolution and frame rate.
+  // |constraints| decides video resolution and frame rate but can
   // be NULL.
+  // In the NULL case, use the version above.
   virtual rtc::scoped_refptr<VideoSourceInterface> CreateVideoSource(
       cricket::VideoCapturer* capturer,
       const MediaConstraintsInterface* constraints) = 0;
diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc
index 8fad21e..6d324c0 100644
--- a/webrtc/api/peerconnectioninterface_unittest.cc
+++ b/webrtc/api/peerconnectioninterface_unittest.cc
@@ -2454,11 +2454,11 @@
   rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
 
   cricket::MediaSessionOptions options;
-  EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, &options));
 
   rtc_options.offer_to_receive_audio =
       RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
-  EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, &options));
 }
 
 TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) {
@@ -2466,11 +2466,11 @@
   rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
 
   cricket::MediaSessionOptions options;
-  EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, &options));
 
   rtc_options.offer_to_receive_video =
       RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
-  EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, &options));
 }
 
 // Test that a MediaSessionOptions is created for an offer if
@@ -2481,7 +2481,7 @@
   rtc_options.offer_to_receive_video = 1;
 
   cricket::MediaSessionOptions options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_TRUE(options.has_audio());
   EXPECT_TRUE(options.has_video());
   EXPECT_TRUE(options.bundle_enabled);
@@ -2494,7 +2494,7 @@
   rtc_options.offer_to_receive_audio = 1;
 
   cricket::MediaSessionOptions options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_TRUE(options.has_audio());
   EXPECT_FALSE(options.has_video());
   EXPECT_TRUE(options.bundle_enabled);
@@ -2508,7 +2508,7 @@
   cricket::MediaSessionOptions options;
   options.transport_options["audio"] = cricket::TransportOptions();
   options.transport_options["video"] = cricket::TransportOptions();
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_TRUE(options.has_audio());
   EXPECT_FALSE(options.has_video());
   EXPECT_TRUE(options.bundle_enabled);
@@ -2525,7 +2525,7 @@
   rtc_options.offer_to_receive_video = 1;
 
   cricket::MediaSessionOptions options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_FALSE(options.has_audio());
   EXPECT_TRUE(options.has_video());
   EXPECT_TRUE(options.bundle_enabled);
@@ -2541,7 +2541,7 @@
   rtc_options.use_rtp_mux = false;
 
   cricket::MediaSessionOptions options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_TRUE(options.has_audio());
   EXPECT_TRUE(options.has_video());
   EXPECT_FALSE(options.bundle_enabled);
@@ -2557,12 +2557,12 @@
   cricket::MediaSessionOptions options;
   options.transport_options["audio"] = cricket::TransportOptions();
   options.transport_options["video"] = cricket::TransportOptions();
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_TRUE(options.transport_options["audio"].ice_restart);
   EXPECT_TRUE(options.transport_options["video"].ice_restart);
 
   rtc_options = RTCOfferAnswerOptions();
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, &options));
   EXPECT_FALSE(options.transport_options["audio"].ice_restart);
   EXPECT_FALSE(options.transport_options["video"].ice_restart);
 }
@@ -2584,7 +2584,7 @@
   RTCOfferAnswerOptions rtc_offer_options;
 
   cricket::MediaSessionOptions offer_options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_offer_options, &offer_options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(rtc_offer_options, &offer_options));
   EXPECT_TRUE(offer_options.has_audio());
   EXPECT_FALSE(offer_options.has_video());
 
@@ -2593,8 +2593,8 @@
   updated_rtc_offer_options.offer_to_receive_video = 1;
 
   cricket::MediaSessionOptions updated_offer_options;
-  EXPECT_TRUE(ConvertRtcOptionsForOffer(updated_rtc_offer_options,
-                                        &updated_offer_options));
+  EXPECT_TRUE(ExtractMediaSessionOptions(updated_rtc_offer_options,
+                                         &updated_offer_options));
   EXPECT_TRUE(updated_offer_options.has_audio());
   EXPECT_TRUE(updated_offer_options.has_video());
 
diff --git a/webrtc/api/peerconnectionproxy.h b/webrtc/api/peerconnectionproxy.h
index 04a3737..e47bc96 100644
--- a/webrtc/api/peerconnectionproxy.h
+++ b/webrtc/api/peerconnectionproxy.h
@@ -50,6 +50,14 @@
                 const MediaConstraintsInterface*)
   PROXY_METHOD2(void, CreateAnswer, CreateSessionDescriptionObserver*,
                 const MediaConstraintsInterface*)
+  PROXY_METHOD2(void,
+                CreateOffer,
+                CreateSessionDescriptionObserver*,
+                const RTCOfferAnswerOptions&)
+  PROXY_METHOD2(void,
+                CreateAnswer,
+                CreateSessionDescriptionObserver*,
+                const RTCOfferAnswerOptions&)
   PROXY_METHOD2(void, SetLocalDescription, SetSessionDescriptionObserver*,
                 SessionDescriptionInterface*)
   PROXY_METHOD2(void, SetRemoteDescription, SetSessionDescriptionObserver*,
diff --git a/webrtc/api/videosource.cc b/webrtc/api/videosource.cc
index a15ed19..445b92d 100644
--- a/webrtc/api/videosource.cc
+++ b/webrtc/api/videosource.cc
@@ -287,6 +287,13 @@
   return source;
 }
 
+rtc::scoped_refptr<VideoSource> VideoSource::Create(
+    rtc::Thread* worker_thread,
+    cricket::VideoCapturer* capturer,
+    bool remote) {
+  return Create(worker_thread, capturer, nullptr, remote);
+}
+
 VideoSource::VideoSource(rtc::Thread* worker_thread,
                          cricket::VideoCapturer* capturer,
                          bool remote)
diff --git a/webrtc/api/videosource.h b/webrtc/api/videosource.h
index 634c47a..eb46463 100644
--- a/webrtc/api/videosource.h
+++ b/webrtc/api/videosource.h
@@ -47,6 +47,13 @@
       const webrtc::MediaConstraintsInterface* constraints,
       bool remote);
 
+  // Note that the non-constraints version does not have the ability to
+  // select configuration based on width, height, aspect ratio or frame rate.
+  static rtc::scoped_refptr<VideoSource> Create(
+      rtc::Thread* worker_thread,
+      cricket::VideoCapturer* capturer,
+      bool remote);
+
   SourceState state() const override { return state_; }
   bool remote() const override { return remote_; }
 
diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc
index 2c414a9..57f80c7 100644
--- a/webrtc/api/webrtcsession.cc
+++ b/webrtc/api/webrtcsession.cc
@@ -19,7 +19,6 @@
 
 #include "webrtc/api/jsepicecandidate.h"
 #include "webrtc/api/jsepsessiondescription.h"
-#include "webrtc/api/mediaconstraintsinterface.h"
 #include "webrtc/api/peerconnectioninterface.h"
 #include "webrtc/api/sctputils.h"
 #include "webrtc/api/webrtcsessiondescriptionfactory.h"
@@ -422,25 +421,6 @@
   return MakeErrorString(kPushDownTDFailed, desc);
 }
 
-// Set |option| to the highest-priority value of |key| in the optional
-// constraints if the key is found and has a valid value.
-template <typename T>
-static void SetOptionFromOptionalConstraint(
-    const MediaConstraintsInterface* constraints,
-    const std::string& key,
-    rtc::Optional<T>* option) {
-  if (!constraints) {
-    return;
-  }
-  std::string string_value;
-  T value;
-  if (constraints->GetOptional().FindFirst(key, &string_value)) {
-    if (rtc::FromString(string_value, &value)) {
-      *option = rtc::Optional<T>(value);
-    }
-  }
-}
-
 uint32_t ConvertIceTransportTypeToCandidateFilter(
     PeerConnectionInterface::IceTransportsType type) {
   switch (type) {
@@ -546,7 +526,6 @@
 
 bool WebRtcSession::Initialize(
     const PeerConnectionFactoryInterface::Options& options,
-    const MediaConstraintsInterface* constraints,
     rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
     const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
   bundle_policy_ = rtc_configuration.bundle_policy;
@@ -564,46 +543,33 @@
 
   SetIceConfig(ParseIceConfig(rtc_configuration));
 
-  // TODO(perkj): Take |constraints| into consideration. Return false if not all
-  // mandatory constraints can be fulfilled. Note that |constraints|
-  // can be null.
-  bool value;
-
   if (options.disable_encryption) {
     dtls_enabled_ = false;
   } else {
     // Enable DTLS by default if we have an identity store or a certificate.
     dtls_enabled_ = (dtls_identity_store || certificate);
-    // |constraints| can override the default |dtls_enabled_| value.
-    if (FindConstraint(constraints, MediaConstraintsInterface::kEnableDtlsSrtp,
-                       &value, nullptr)) {
-      dtls_enabled_ = value;
+    // |rtc_configuration| can override the default |dtls_enabled_| value.
+    if (rtc_configuration.enable_dtls_srtp) {
+      dtls_enabled_ = *(rtc_configuration.enable_dtls_srtp);
     }
   }
 
   // Enable creation of RTP data channels if the kEnableRtpDataChannels is set.
   // It takes precendence over the disable_sctp_data_channels
   // PeerConnectionFactoryInterface::Options.
-  if (FindConstraint(
-      constraints, MediaConstraintsInterface::kEnableRtpDataChannels,
-      &value, NULL) && value) {
-    LOG(LS_INFO) << "Allowing RTP data engine.";
+  if (rtc_configuration.enable_rtp_data_channel) {
     data_channel_type_ = cricket::DCT_RTP;
   } else {
     // DTLS has to be enabled to use SCTP.
     if (!options.disable_sctp_data_channels && dtls_enabled_) {
-      LOG(LS_INFO) << "Allowing SCTP data engine.";
       data_channel_type_ = cricket::DCT_SCTP;
     }
   }
 
-  SetOptionFromOptionalConstraint(constraints,
-      MediaConstraintsInterface::kScreencastMinBitrate,
-      &video_options_.screencast_min_bitrate_kbps);
-
-  SetOptionFromOptionalConstraint(constraints,
-      MediaConstraintsInterface::kCombinedAudioVideoBwe,
-      &audio_options_.combined_audio_video_bwe);
+  video_options_.screencast_min_bitrate_kbps =
+      rtc_configuration.screencast_min_bitrate;
+  audio_options_.combined_audio_video_bwe =
+      rtc_configuration.combined_audio_video_bwe;
 
   audio_options_.audio_jitter_buffer_max_packets =
       rtc::Optional<int>(rtc_configuration.audio_jitter_buffer_max_packets);
@@ -698,10 +664,8 @@
 
 void WebRtcSession::CreateAnswer(
     CreateSessionDescriptionObserver* observer,
-    const MediaConstraintsInterface* constraints,
     const cricket::MediaSessionOptions& session_options) {
-  webrtc_session_desc_factory_->CreateAnswer(observer, constraints,
-                                             session_options);
+  webrtc_session_desc_factory_->CreateAnswer(observer, session_options);
 }
 
 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h
index 70265d3..87379ab 100644
--- a/webrtc/api/webrtcsession.h
+++ b/webrtc/api/webrtcsession.h
@@ -147,7 +147,6 @@
 
   bool Initialize(
       const PeerConnectionFactoryInterface::Options& options,
-      const MediaConstraintsInterface* constraints,
       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
       const PeerConnectionInterface::RTCConfiguration& rtc_configuration);
   // Deletes the voice, video and data channel and changes the session state
@@ -197,7 +196,6 @@
       const PeerConnectionInterface::RTCOfferAnswerOptions& options,
       const cricket::MediaSessionOptions& session_options);
   void CreateAnswer(CreateSessionDescriptionObserver* observer,
-                    const MediaConstraintsInterface* constraints,
                     const cricket::MediaSessionOptions& session_options);
   // The ownership of |desc| will be transferred after this call.
   bool SetLocalDescription(SessionDescriptionInterface* desc,
diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc
index fc0d0cc..f503db3 100644
--- a/webrtc/api/webrtcsession_unittest.cc
+++ b/webrtc/api/webrtcsession_unittest.cc
@@ -20,7 +20,6 @@
 #include "webrtc/api/sctputils.h"
 #include "webrtc/api/streamcollection.h"
 #include "webrtc/api/streamcollection.h"
-#include "webrtc/api/test/fakeconstraints.h"
 #include "webrtc/api/test/fakedtlsidentitystore.h"
 #include "webrtc/api/videotrack.h"
 #include "webrtc/api/webrtcsession.h"
@@ -65,7 +64,6 @@
 using webrtc::CreateSessionDescriptionRequest;
 using webrtc::DataChannel;
 using webrtc::DtlsIdentityStoreInterface;
-using webrtc::FakeConstraints;
 using webrtc::FakeMetricsObserver;
 using webrtc::IceCandidateCollection;
 using webrtc::InternalDataChannelInit;
@@ -369,8 +367,7 @@
   // used if provided, otherwise one will be generated using the
   // |dtls_identity_store|.
   void Init(
-      rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
-      const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
+      rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store) {
     ASSERT_TRUE(session_.get() == NULL);
     session_.reset(new WebRtcSessionForTest(
         media_controller_.get(), rtc::Thread::Current(), rtc::Thread::Current(),
@@ -385,9 +382,8 @@
     EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
         observer_.ice_gathering_state_);
 
-    EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
-                                     std::move(dtls_identity_store),
-                                     rtc_configuration));
+    EXPECT_TRUE(session_->Initialize(options_, std::move(dtls_identity_store),
+                                     configuration_));
     session_->set_metrics_observer(metrics_observer_);
   }
 
@@ -399,39 +395,33 @@
 
   void OnSessionDestroyed() { session_destroyed_ = true; }
 
-  void Init() {
-    PeerConnectionInterface::RTCConfiguration configuration;
-    Init(nullptr, configuration);
-  }
+  void Init() { Init(nullptr); }
 
   void InitWithIceTransport(
       PeerConnectionInterface::IceTransportsType ice_transport_type) {
-    PeerConnectionInterface::RTCConfiguration configuration;
-    configuration.type = ice_transport_type;
-    Init(nullptr, configuration);
+    configuration_.type = ice_transport_type;
+    Init();
   }
 
   void InitWithBundlePolicy(
       PeerConnectionInterface::BundlePolicy bundle_policy) {
-    PeerConnectionInterface::RTCConfiguration configuration;
-    configuration.bundle_policy = bundle_policy;
-    Init(nullptr, configuration);
+    configuration_.bundle_policy = bundle_policy;
+    Init();
   }
 
   void InitWithRtcpMuxPolicy(
       PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
     PeerConnectionInterface::RTCConfiguration configuration;
-    configuration.rtcp_mux_policy = rtcp_mux_policy;
-    Init(nullptr, configuration);
+    configuration_.rtcp_mux_policy = rtcp_mux_policy;
+    Init();
   }
 
   // Successfully init with DTLS; with a certificate generated and supplied or
   // with a store that generates it for us.
   void InitWithDtls(RTCCertificateGenerationMethod cert_gen_method) {
     rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store;
-    PeerConnectionInterface::RTCConfiguration configuration;
     if (cert_gen_method == ALREADY_GENERATED) {
-      configuration.certificates.push_back(
+      configuration_.certificates.push_back(
           FakeDtlsIdentityStore::GenerateCertificate());
     } else if (cert_gen_method == DTLS_IDENTITY_STORE) {
       dtls_identity_store.reset(new FakeDtlsIdentityStore());
@@ -439,7 +429,7 @@
     } else {
       RTC_CHECK(false);
     }
-    Init(std::move(dtls_identity_store), configuration);
+    Init(std::move(dtls_identity_store));
   }
 
   // Init with DTLS with a store that will fail to generate a certificate.
@@ -447,8 +437,7 @@
     rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
         new FakeDtlsIdentityStore());
     dtls_identity_store->set_should_fail(true);
-    PeerConnectionInterface::RTCConfiguration configuration;
-    Init(std::move(dtls_identity_store), configuration);
+    Init(std::move(dtls_identity_store));
   }
 
   void InitWithDtmfCodec() {
@@ -531,7 +520,7 @@
   void GetOptionsForOffer(
       const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
       cricket::MediaSessionOptions* session_options) {
-    ASSERT_TRUE(ConvertRtcOptionsForOffer(rtc_options, session_options));
+    ASSERT_TRUE(ExtractMediaSessionOptions(rtc_options, session_options));
 
     AddStreamsToOptions(session_options);
     if (rtc_options.offer_to_receive_audio ==
@@ -554,11 +543,9 @@
     }
   }
 
-  void GetOptionsForAnswer(const webrtc::MediaConstraintsInterface* constraints,
-                           cricket::MediaSessionOptions* session_options) {
-    session_options->recv_audio = false;
-    session_options->recv_video = false;
-    ASSERT_TRUE(ParseConstraintsForAnswer(constraints, session_options));
+  void GetOptionsForAnswer(cricket::MediaSessionOptions* session_options) {
+    // ParseConstraintsForAnswer is used to set some defaults.
+    ASSERT_TRUE(webrtc::ParseConstraintsForAnswer(nullptr, session_options));
 
     AddStreamsToOptions(session_options);
     session_options->bundle_enabled =
@@ -591,7 +578,7 @@
   }
 
   SessionDescriptionInterface* CreateOffer(
-      const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
+      const PeerConnectionInterface::RTCOfferAnswerOptions options) {
     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
         observer = new WebRtcSessionCreateSDPObserverForTest();
     cricket::MediaSessionOptions session_options;
@@ -604,18 +591,28 @@
   }
 
   SessionDescriptionInterface* CreateAnswer(
-      const webrtc::MediaConstraintsInterface* constraints) {
+      const cricket::MediaSessionOptions& options) {
     rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
         = new WebRtcSessionCreateSDPObserverForTest();
-    cricket::MediaSessionOptions session_options;
-    GetOptionsForAnswer(constraints, &session_options);
-    session_->CreateAnswer(observer, constraints, session_options);
+    cricket::MediaSessionOptions session_options = options;
+    GetOptionsForAnswer(&session_options);
+    // Overwrite recv_audio and recv_video with passed-in values.
+    session_options.recv_video = options.recv_video;
+    session_options.recv_audio = options.recv_audio;
+    session_->CreateAnswer(observer, session_options);
     EXPECT_TRUE_WAIT(
         observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
         2000);
     return observer->ReleaseDescription();
   }
 
+  SessionDescriptionInterface* CreateAnswer() {
+    cricket::MediaSessionOptions options;
+    options.recv_video = true;
+    options.recv_audio = true;
+    return CreateAnswer(options);
+  }
+
   bool ChannelsExist() const {
     return (session_->voice_channel() != NULL &&
             session_->video_channel() != NULL);
@@ -712,7 +709,7 @@
     VerifyNoCryptoParams(offer->description(), false);
     SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
                                          offer);
-    const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
+    const webrtc::SessionDescriptionInterface* answer = CreateAnswer();
     // Answer should be NULL as no crypto params in offer.
     ASSERT_TRUE(answer == NULL);
   }
@@ -726,7 +723,7 @@
     ASSERT_TRUE(offer.get() != NULL);
     VerifyCryptoParams(offer->description());
     SetRemoteDescriptionWithoutError(offer.release());
-    scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+    scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
     ASSERT_TRUE(answer.get() != NULL);
     VerifyCryptoParams(answer->description());
   }
@@ -838,7 +835,7 @@
   void CreateAndSetRemoteOfferAndLocalAnswer() {
     SessionDescriptionInterface* offer = CreateRemoteOffer();
     SetRemoteDescriptionWithoutError(offer);
-    SessionDescriptionInterface* answer = CreateAnswer(NULL);
+    SessionDescriptionInterface* answer = CreateAnswer();
     SetLocalDescriptionWithoutError(answer);
   }
   void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
@@ -1013,7 +1010,7 @@
   // before this function to decide which streams to create.
   JsepSessionDescription* CreateRemoteOffer() {
     cricket::MediaSessionOptions options;
-    GetOptionsForAnswer(NULL, &options);
+    GetOptionsForAnswer(&options);
     return CreateRemoteOffer(options, session_->remote_description());
   }
 
@@ -1047,7 +1044,7 @@
   JsepSessionDescription* CreateRemoteAnswer(
       const SessionDescriptionInterface* offer) {
     cricket::MediaSessionOptions options;
-    GetOptionsForAnswer(NULL, &options);
+    GetOptionsForAnswer(&options);
     return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
   }
 
@@ -1334,6 +1331,7 @@
 
   void CreateDataChannel() {
     webrtc::InternalDataChannelInit dci;
+    ASSERT(session_.get());
     dci.reliable = session_->data_channel_type() == cricket::DCT_SCTP;
     data_channel_ = DataChannel::Create(
         session_.get(), session_->data_channel_type(), "datachannel", dci);
@@ -1380,7 +1378,7 @@
       if (type == CreateSessionDescriptionRequest::kOffer) {
         session_->CreateOffer(observers[i], options, session_options);
       } else {
-        session_->CreateAnswer(observers[i], nullptr, session_options);
+        session_->CreateAnswer(observers[i], session_options);
       }
     }
 
@@ -1426,7 +1424,7 @@
   rtc::FakeNetworkManager network_manager_;
   rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
   PeerConnectionFactoryInterface::Options options_;
-  rtc::scoped_ptr<FakeConstraints> constraints_;
+  PeerConnectionInterface::RTCConfiguration configuration_;
   rtc::scoped_ptr<WebRtcSessionForTest> session_;
   MockIceObserver observer_;
   cricket::FakeVideoMediaChannel* video_channel_;
@@ -1620,7 +1618,7 @@
   SetRemoteDescriptionWithoutError(offer);
 
   SendAudioVideoStream1();
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   VerifyCryptoParams(answer->description());
   SetLocalDescriptionWithoutError(answer);
 
@@ -1630,6 +1628,8 @@
   video_channel_ = media_engine_->GetVideoChannel(0);
   voice_channel_ = media_engine_->GetVoiceChannel(0);
 
+  ASSERT_TRUE(video_channel_);
+  ASSERT_TRUE(voice_channel_);
   ASSERT_EQ(1u, video_channel_->recv_streams().size());
   EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
 
@@ -1647,7 +1647,7 @@
 
   // Answer by turning off all send streams.
   SendNothing();
-  answer = CreateAnswer(NULL);
+  answer = CreateAnswer();
 
   // Verify the session id is the same and the session version is
   // increased.
@@ -1775,7 +1775,7 @@
   SetRemoteDescriptionWithoutError(offer);
 
   // Verify that we get a crypto fingerprint in the answer.
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   ASSERT_TRUE(answer != NULL);
   VerifyFingerprintStatus(answer->description(), true);
   // Check that we don't have an a=crypto line in the answer.
@@ -1922,7 +1922,7 @@
   SetRemoteDescriptionWithoutError(offer);
 
   // Verify that we get a crypto fingerprint in the answer.
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   ASSERT_TRUE(answer != NULL);
   VerifyFingerprintStatus(answer->description(), false);
   // Check that we don't have an a=crypto line in the answer.
@@ -1966,7 +1966,7 @@
                                        session_->remote_description());
   SetRemoteDescriptionWithoutError(offer);
 
-  answer = CreateAnswer(nullptr);
+  answer = CreateAnswer();
   audio_transport_info = answer->description()->GetTransportInfoByName("audio");
   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
             audio_transport_info->description.connection_role);
@@ -1983,7 +1983,7 @@
                                        kSessionVersion,
                                        session_->remote_description());
   SetRemoteDescriptionWithoutError(offer);
-  answer = CreateAnswer(nullptr);
+  answer = CreateAnswer();
   audio_transport_info = answer->description()->GetTransportInfoByName("audio");
   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
             audio_transport_info->description.connection_role);
@@ -2042,20 +2042,20 @@
   SessionDescriptionInterface* offer = CreateRemoteOffer();
   SetRemoteDescriptionExpectState(offer, WebRtcSession::STATE_RECEIVEDOFFER);
 
-  JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
-      CreateAnswer(NULL));
+  JsepSessionDescription* pranswer =
+      static_cast<JsepSessionDescription*>(CreateAnswer());
   pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
   SetLocalDescriptionExpectState(pranswer, WebRtcSession::STATE_SENTPRANSWER);
 
   SendAudioVideoStream1();
-  JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
-      CreateAnswer(NULL));
+  JsepSessionDescription* pranswer2 =
+      static_cast<JsepSessionDescription*>(CreateAnswer());
   pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
 
   SetLocalDescriptionExpectState(pranswer2, WebRtcSession::STATE_SENTPRANSWER);
 
   SendAudioVideoStream2();
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionExpectState(answer, WebRtcSession::STATE_INPROGRESS);
 }
 
@@ -2270,7 +2270,7 @@
   ASSERT_EQ(1u, candidates->count());
   EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
 
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 }
 
@@ -2296,7 +2296,7 @@
 
   SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(remote_offer);
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
   EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
   SetLocalDescriptionWithoutError(answer);
@@ -2337,8 +2337,7 @@
 
   SetRemoteDescriptionWithoutError(modified_offer);
 
-  SessionDescriptionInterface* answer =
-      CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 
   cricket::TransportChannel* voice_transport_channel =
@@ -2347,7 +2346,7 @@
   EXPECT_EQ(voice_transport_channel->transport_name(), "audio_content_name");
   cricket::TransportChannel* video_transport_channel =
       session_->video_rtp_transport_channel();
-  EXPECT_TRUE(video_transport_channel != NULL);
+  ASSERT_TRUE(video_transport_channel != NULL);
   EXPECT_EQ(video_transport_channel->transport_name(), "video_content_name");
   EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
   EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
@@ -2468,7 +2467,7 @@
   SetLocalDescriptionWithoutError(offer);
   SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
   SetRemoteDescriptionWithoutError(answer);
-  EXPECT_TRUE(CreateAnswer(NULL) == NULL);
+  EXPECT_TRUE(CreateAnswer() == NULL);
 }
 
 // Test that an answer contains the correct media content descriptions when no
@@ -2478,8 +2477,7 @@
   // Create a remote offer with audio and video content.
   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
   ASSERT_TRUE(content != NULL);
@@ -2503,8 +2501,7 @@
   ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
 
   SetRemoteDescriptionWithoutError(offer.release());
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
   ASSERT_TRUE(content != NULL);
@@ -2522,8 +2519,7 @@
   SetRemoteDescriptionWithoutError(offer.release());
   // Test with a stream with tracks.
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
   ASSERT_TRUE(content != NULL);
@@ -2542,12 +2538,12 @@
   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
-  webrtc::FakeConstraints constraints_no_receive;
-  constraints_no_receive.SetMandatoryReceiveAudio(false);
-  constraints_no_receive.SetMandatoryReceiveVideo(false);
-
+  cricket::MediaSessionOptions session_options;
+  session_options.recv_audio = false;
+  session_options.recv_video = false;
   rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(&constraints_no_receive));
+      CreateAnswer(session_options));
+
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
   ASSERT_TRUE(content != NULL);
@@ -2566,14 +2562,13 @@
   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
-  webrtc::FakeConstraints constraints_no_receive;
-  constraints_no_receive.SetMandatoryReceiveAudio(false);
-  constraints_no_receive.SetMandatoryReceiveVideo(false);
+  cricket::MediaSessionOptions options;
+  options.recv_audio = false;
+  options.recv_video = false;
 
   // Test with a stream with tracks.
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(&constraints_no_receive));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(options));
 
   // TODO(perkj): Should the direction be set to SEND_ONLY?
   const cricket::ContentInfo* content =
@@ -2611,10 +2606,9 @@
   rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
   SetRemoteDescriptionWithoutError(offer.release());
 
-  webrtc::FakeConstraints constraints;
-  constraints.SetOptionalVAD(false);
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(&constraints));
+  cricket::MediaSessionOptions options;
+  options.vad_enabled = false;
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(options));
   const cricket::ContentInfo* content =
       cricket::GetFirstAudioContent(answer->description());
   ASSERT_TRUE(content != NULL);
@@ -2739,7 +2733,7 @@
   scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   VerifyCryptoParams(offer->description());
   SetRemoteDescriptionWithoutError(offer.release());
-  scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+  scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   VerifyCryptoParams(answer->description());
 }
 
@@ -2927,7 +2921,7 @@
   SessionDescriptionInterface* offer = CreateRemoteOffer();
   SetRemoteDescriptionWithoutError(offer);
 
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 
   EXPECT_EQ(session_->voice_rtp_transport_channel(),
@@ -3150,7 +3144,7 @@
             session_->video_rtp_transport_channel());
 
   SendAudioVideoStream2();
-  SessionDescriptionInterface* answer = CreateAnswer(nullptr);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 
   EXPECT_EQ(session_->voice_rtp_transport_channel(),
@@ -3467,7 +3461,7 @@
   EXPECT_FALSE(session_->initial_offerer());
   SessionDescriptionInterface* offer = CreateRemoteOffer();
   SetRemoteDescriptionWithoutError(offer);
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
 
   EXPECT_FALSE(session_->initial_offerer());
   SetLocalDescriptionWithoutError(answer);
@@ -3528,7 +3522,7 @@
   SendAudioVideoStream1();
   SessionDescriptionInterface* offer = CreateRemoteOffer();
   SetRemoteDescriptionWithoutError(offer);
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
 
   cricket::SessionDescription* answer_copy = answer->description()->Copy();
   answer_copy->RemoveContentByName("video");
@@ -3567,7 +3561,7 @@
   EXPECT_TRUE(observer_.mline_0_candidates_.empty());
   EXPECT_TRUE(observer_.mline_1_candidates_.empty());
 
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
   EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
 }
@@ -3621,8 +3615,7 @@
   SetRemoteDescriptionWithoutError(offer.release());
 
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer with new ufrag and password.
@@ -3634,16 +3627,14 @@
       CreateRemoteOffer(options, session_->remote_description()));
   SetRemoteDescriptionWithoutError(updated_offer1.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(CreateAnswer());
 
   EXPECT_FALSE(IceUfragPwdEqual(updated_answer1->description(),
                                 session_->local_description()->description()));
 
   // Even a second answer (created before the description is set) should have
   // a new ufrag/password.
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
 
   EXPECT_FALSE(IceUfragPwdEqual(updated_answer2->description(),
                                 session_->local_description()->description()));
@@ -3667,7 +3658,7 @@
   SetRemoteDescriptionWithoutError(offer.release());
 
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(nullptr));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer with a new ufrag but stale password.
@@ -3677,8 +3668,7 @@
                  "original_password12345");
   SetRemoteDescriptionWithoutError(ufrag_changed_offer.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
-      CreateAnswer(nullptr));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(CreateAnswer());
   EXPECT_FALSE(IceUfragPwdEqual(updated_answer1->description(),
                                 session_->local_description()->description()));
   SetLocalDescriptionWithoutError(updated_answer1.release());
@@ -3690,8 +3680,7 @@
                  "modified_password12345");
   SetRemoteDescriptionWithoutError(password_changed_offer.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
-      CreateAnswer(nullptr));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
   EXPECT_FALSE(IceUfragPwdEqual(updated_answer2->description(),
                                 session_->local_description()->description()));
   SetLocalDescriptionWithoutError(updated_answer2.release());
@@ -3708,8 +3697,7 @@
   SetRemoteDescriptionWithoutError(offer.release());
 
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer without changed ufrag or password.
@@ -3717,8 +3705,7 @@
       CreateRemoteOffer(options, session_->remote_description()));
   SetRemoteDescriptionWithoutError(updated_offer2.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
-      CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
 
   EXPECT_TRUE(IceUfragPwdEqual(updated_answer2->description(),
                                session_->local_description()->description()));
@@ -3744,7 +3731,7 @@
   SetRemoteDescriptionWithoutError(offer.release());
 
   SendAudioVideoStream1();
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(nullptr));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   SetLocalDescriptionWithoutError(answer.release());
 
   // Receive an offer with new ufrag and password, but only for the video media
@@ -3755,8 +3742,7 @@
                  "cccccccccccccccccccccc");
   SetRemoteDescriptionWithoutError(updated_offer.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer(
-      CreateAnswer(nullptr));
+  rtc::scoped_ptr<SessionDescriptionInterface> updated_answer(CreateAnswer());
 
   EXPECT_TRUE(IceUfragPwdEqual(updated_answer->description(),
                                session_->local_description()->description(),
@@ -3825,21 +3811,17 @@
 }
 
 TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
-  constraints_.reset(new FakeConstraints());
-  constraints_->AddOptional(
-      webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
+  configuration_.enable_rtp_data_channel = true;
   Init();
-
   SetLocalDescriptionWithDataChannel();
+  ASSERT_TRUE(data_engine_);
   EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
 }
 
 TEST_P(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
 
-  constraints_.reset(new FakeConstraints());
-  constraints_->AddOptional(
-      webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
+  configuration_.enable_rtp_data_channel = true;
   options_.disable_sctp_data_channels = false;
 
   InitWithDtls(GetParam());
@@ -3871,16 +3853,14 @@
   SetRemoteDescriptionWithoutError(offer);
 
   // Verifies the answer contains SCTP.
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   EXPECT_TRUE(answer != NULL);
   EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
   EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
 }
 
 TEST_P(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
-  constraints_.reset(new FakeConstraints());
-  constraints_->AddOptional(
-      webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
+  configuration_.enable_dtls_srtp = rtc::Optional<bool>(false);
   InitWithDtls(GetParam());
 
   SetLocalDescriptionWithDataChannel();
@@ -3924,8 +3904,8 @@
   // SetRemoteDescription will take the ownership of the offer.
   SetRemoteDescriptionWithoutError(offer);
 
-  SessionDescriptionInterface* answer = ChangeSDPSctpPort(
-      new_recv_port, CreateAnswer(NULL));
+  SessionDescriptionInterface* answer =
+      ChangeSDPSctpPort(new_recv_port, CreateAnswer());
   ASSERT_TRUE(answer != NULL);
 
   // Now set the local description, which'll take ownership of the answer.
@@ -3989,9 +3969,8 @@
   rtc::scoped_refptr<rtc::RTCCertificate> certificate =
       FakeDtlsIdentityStore::GenerateCertificate();
 
-  PeerConnectionInterface::RTCConfiguration configuration;
-  configuration.certificates.push_back(certificate);
-  Init(nullptr, configuration);
+  configuration_.certificates.push_back(certificate);
+  Init();
   EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
 
   EXPECT_EQ(session_->certificate_for_testing(), certificate);
@@ -4028,7 +4007,7 @@
   ASSERT_TRUE(offer.get() != NULL);
   SetRemoteDescriptionWithoutError(offer.release());
 
-  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
+  rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer());
   EXPECT_TRUE(answer != NULL);
   VerifyNoCryptoParams(answer->description(), true);
   VerifyFingerprintStatus(answer->description(), true);
@@ -4117,10 +4096,7 @@
 }
 
 TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
-  constraints_.reset(new FakeConstraints());
-  constraints_->AddOptional(
-      webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
-      true);
+  configuration_.combined_audio_video_bwe = rtc::Optional<bool>(true);
   Init();
   SendAudioVideoStream1();
   SessionDescriptionInterface* offer = CreateOffer();
@@ -4160,7 +4136,7 @@
   EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
   SetRemoteDescriptionWithoutError(offer);
 
-  answer = CreateAnswer(NULL);
+  answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 }
 
@@ -4190,7 +4166,7 @@
                                  candidate1);
   EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
 
-  answer = CreateAnswer(NULL);
+  answer = CreateAnswer();
   SetLocalDescriptionWithoutError(answer);
 }
 
@@ -4215,7 +4191,7 @@
   EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
   SetRemoteDescriptionWithoutError(offer);
 
-  SessionDescriptionInterface* answer = CreateAnswer(NULL);
+  SessionDescriptionInterface* answer = CreateAnswer();
   std::string answer_sdp;
   answer->ToString(&answer_sdp);
   // Answer SDP removes the unsupported RTX codec.
diff --git a/webrtc/api/webrtcsessiondescriptionfactory.cc b/webrtc/api/webrtcsessiondescriptionfactory.cc
index 34cc438..78840e2 100644
--- a/webrtc/api/webrtcsessiondescriptionfactory.cc
+++ b/webrtc/api/webrtcsessiondescriptionfactory.cc
@@ -282,7 +282,6 @@
 
 void WebRtcSessionDescriptionFactory::CreateAnswer(
     CreateSessionDescriptionObserver* observer,
-    const MediaConstraintsInterface* constraints,
     const cricket::MediaSessionOptions& session_options) {
   std::string error = "CreateAnswer";
   if (certificate_request_state_ == CERTIFICATE_FAILED) {
diff --git a/webrtc/api/webrtcsessiondescriptionfactory.h b/webrtc/api/webrtcsessiondescriptionfactory.h
index b58b55d..71d083b 100644
--- a/webrtc/api/webrtcsessiondescriptionfactory.h
+++ b/webrtc/api/webrtcsessiondescriptionfactory.h
@@ -106,7 +106,6 @@
       const PeerConnectionInterface::RTCOfferAnswerOptions& options,
       const cricket::MediaSessionOptions& session_options);
   void CreateAnswer(CreateSessionDescriptionObserver* observer,
-                    const MediaConstraintsInterface* constraints,
                     const cricket::MediaSessionOptions& session_options);
 
   void SetSdesPolicy(cricket::SecurePolicy secure_policy);