Move MediaConstraintsInterface to sdk/, and make it a concrete class

Bug: webrtc:9239
Change-Id: I545ebf59b078dd94bc466886616dd374e4b2e226
Reviewed-on: https://webrtc-review.googlesource.com/c/122502
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26682}
diff --git a/BUILD.gn b/BUILD.gn
index a62bb02..0f68aac 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -496,6 +496,7 @@
       "rtc_base:sigslot_unittest",
       "rtc_base:weak_ptr_unittests",
       "rtc_base/experiments:experiments_unittests",
+      "sdk:sdk_tests",
       "test/scenario/network:network_emulation_unittests",
     ]
 
diff --git a/api/BUILD.gn b/api/BUILD.gn
index a3e659c..aacc1e4 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -86,8 +86,6 @@
     "jsep_ice_candidate.cc",
     "jsep_ice_candidate.h",
     "jsep_session_description.h",
-    "media_constraints_interface.cc",
-    "media_constraints_interface.h",
     "media_stream_interface.cc",
     "media_stream_interface.h",
     "media_stream_proxy.h",
@@ -364,19 +362,6 @@
   ]
 }
 
-rtc_source_set("libjingle_peerconnection_test_api") {
-  visibility = [ "*" ]
-  testonly = true
-  sources = [
-    "test/fake_constraints.h",
-  ]
-
-  deps = [
-    ":libjingle_peerconnection_api",
-    "../rtc_base:rtc_base_approved",
-  ]
-}
-
 rtc_source_set("neteq_simulator_api") {
   visibility = [ "*" ]
   sources = [
diff --git a/api/media_constraints_interface.cc b/api/media_constraints_interface.cc
deleted file mode 100644
index e16fc19..0000000
--- a/api/media_constraints_interface.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- *  Copyright 2013 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 "api/media_constraints_interface.h"
-
-#include "absl/types/optional.h"
-#include "api/peer_connection_interface.h"
-#include "media/base/media_config.h"
-#include "rtc_base/string_encode.h"
-
-namespace {
-
-// Find the highest-priority instance of the T-valued constraint named by
-// |key| and return its value as |value|. |constraints| can be null.
-// If |mandatory_constraints| is non-null, it is incremented if the key appears
-// among the mandatory constraints.
-// Returns true if the key was found and has a valid value for type T.
-// If the key appears multiple times as an optional constraint, appearances
-// after the first are ignored.
-// Note: Because this uses FindFirst, repeated optional constraints whose
-// first instance has an unrecognized value are not handled precisely in
-// accordance with the specification.
-template <typename T>
-bool FindConstraint(const webrtc::MediaConstraintsInterface* constraints,
-                    const std::string& key,
-                    T* value,
-                    size_t* mandatory_constraints) {
-  std::string string_value;
-  if (!FindConstraint(constraints, key, &string_value, mandatory_constraints)) {
-    return false;
-  }
-  return rtc::FromString(string_value, value);
-}
-
-// Specialization for std::string, since a string doesn't need conversion.
-template <>
-bool FindConstraint(const webrtc::MediaConstraintsInterface* constraints,
-                    const std::string& key,
-                    std::string* value,
-                    size_t* mandatory_constraints) {
-  if (!constraints) {
-    return false;
-  }
-  if (constraints->GetMandatory().FindFirst(key, value)) {
-    if (mandatory_constraints) {
-      ++*mandatory_constraints;
-    }
-    return true;
-  }
-  if (constraints->GetOptional().FindFirst(key, value)) {
-    return true;
-  }
-  return false;
-}
-
-// Converts a constraint (mandatory takes precedence over optional) to an
-// absl::optional.
-template <typename T>
-void ConstraintToOptional(const webrtc::MediaConstraintsInterface* constraints,
-                          const std::string& key,
-                          absl::optional<T>* value_out) {
-  T value;
-  bool present = FindConstraint<T>(constraints, key, &value, nullptr);
-  if (present) {
-    *value_out = value;
-  }
-}
-}  // namespace
-
-namespace webrtc {
-
-const char MediaConstraintsInterface::kValueTrue[] = "true";
-const char MediaConstraintsInterface::kValueFalse[] = "false";
-
-// Constraints declared as static members in mediastreaminterface.h
-
-// Audio constraints.
-const char MediaConstraintsInterface::kGoogEchoCancellation[] =
-    "googEchoCancellation";
-const char MediaConstraintsInterface::kExtendedFilterEchoCancellation[] =
-    "googEchoCancellation2";
-const char MediaConstraintsInterface::kDAEchoCancellation[] =
-    "googDAEchoCancellation";
-const char MediaConstraintsInterface::kAutoGainControl[] =
-    "googAutoGainControl";
-const char MediaConstraintsInterface::kExperimentalAutoGainControl[] =
-    "googAutoGainControl2";
-const char MediaConstraintsInterface::kNoiseSuppression[] =
-    "googNoiseSuppression";
-const char MediaConstraintsInterface::kExperimentalNoiseSuppression[] =
-    "googNoiseSuppression2";
-const char MediaConstraintsInterface::kHighpassFilter[] = "googHighpassFilter";
-const char MediaConstraintsInterface::kTypingNoiseDetection[] =
-    "googTypingNoiseDetection";
-const char MediaConstraintsInterface::kAudioMirroring[] = "googAudioMirroring";
-const char MediaConstraintsInterface::kAudioNetworkAdaptorConfig[] =
-    "googAudioNetworkAdaptorConfig";
-
-// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
-const char MediaConstraintsInterface::kOfferToReceiveAudio[] =
-    "OfferToReceiveAudio";
-const char MediaConstraintsInterface::kOfferToReceiveVideo[] =
-    "OfferToReceiveVideo";
-const char MediaConstraintsInterface::kVoiceActivityDetection[] =
-    "VoiceActivityDetection";
-const char MediaConstraintsInterface::kIceRestart[] = "IceRestart";
-// Google specific constraint for BUNDLE enable/disable.
-const char MediaConstraintsInterface::kUseRtpMux[] = "googUseRtpMUX";
-
-// Below constraints should be used during PeerConnection construction.
-const char MediaConstraintsInterface::kEnableDtlsSrtp[] =
-    "DtlsSrtpKeyAgreement";
-const char MediaConstraintsInterface::kEnableRtpDataChannels[] =
-    "RtpDataChannels";
-// Google-specific constraint keys.
-const char MediaConstraintsInterface::kEnableDscp[] = "googDscp";
-const char MediaConstraintsInterface::kEnableIPv6[] = "googIPv6";
-const char MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate[] =
-    "googSuspendBelowMinBitrate";
-const char MediaConstraintsInterface::kCombinedAudioVideoBwe[] =
-    "googCombinedAudioVideoBwe";
-const char MediaConstraintsInterface::kScreencastMinBitrate[] =
-    "googScreencastMinBitrate";
-// TODO(ronghuawu): Remove once cpu overuse detection is stable.
-const char MediaConstraintsInterface::kCpuOveruseDetection[] =
-    "googCpuOveruseDetection";
-
-const char MediaConstraintsInterface::kNumSimulcastLayers[] =
-    "googNumSimulcastLayers";
-
-// Set |value| to the value associated with the first appearance of |key|, or
-// return false if |key| is not found.
-bool MediaConstraintsInterface::Constraints::FindFirst(
-    const std::string& key,
-    std::string* value) const {
-  for (Constraints::const_iterator iter = begin(); iter != end(); ++iter) {
-    if (iter->key == key) {
-      *value = iter->value;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool FindConstraint(const MediaConstraintsInterface* constraints,
-                    const std::string& key,
-                    bool* value,
-                    size_t* mandatory_constraints) {
-  return ::FindConstraint<bool>(constraints, key, value, mandatory_constraints);
-}
-
-bool FindConstraint(const MediaConstraintsInterface* constraints,
-                    const std::string& key,
-                    int* value,
-                    size_t* mandatory_constraints) {
-  return ::FindConstraint<int>(constraints, key, value, mandatory_constraints);
-}
-
-void CopyConstraintsIntoRtcConfiguration(
-    const MediaConstraintsInterface* constraints,
-    PeerConnectionInterface::RTCConfiguration* configuration) {
-  // Copy info from constraints into configuration, if present.
-  if (!constraints) {
-    return;
-  }
-
-  bool enable_ipv6;
-  if (FindConstraint(constraints, MediaConstraintsInterface::kEnableIPv6,
-                     &enable_ipv6, nullptr)) {
-    configuration->disable_ipv6 = !enable_ipv6;
-  }
-  FindConstraint(constraints, MediaConstraintsInterface::kEnableDscp,
-                 &configuration->media_config.enable_dscp, nullptr);
-  FindConstraint(constraints, MediaConstraintsInterface::kCpuOveruseDetection,
-                 &configuration->media_config.video.enable_cpu_adaptation,
-                 nullptr);
-  FindConstraint(constraints, MediaConstraintsInterface::kEnableRtpDataChannels,
-                 &configuration->enable_rtp_data_channel, nullptr);
-  // Find Suspend Below Min Bitrate constraint.
-  FindConstraint(constraints,
-                 MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
-                 &configuration->media_config.video.suspend_below_min_bitrate,
-                 nullptr);
-  ConstraintToOptional<int>(constraints,
-                            MediaConstraintsInterface::kScreencastMinBitrate,
-                            &configuration->screencast_min_bitrate);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kCombinedAudioVideoBwe,
-                             &configuration->combined_audio_video_bwe);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kEnableDtlsSrtp,
-                             &configuration->enable_dtls_srtp);
-}
-
-void CopyConstraintsIntoAudioOptions(
-    const MediaConstraintsInterface* constraints,
-    cricket::AudioOptions* options) {
-  if (!constraints) {
-    return;
-  }
-
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kGoogEchoCancellation,
-                             &options->echo_cancellation);
-  ConstraintToOptional<bool>(
-      constraints, MediaConstraintsInterface::kExtendedFilterEchoCancellation,
-      &options->extended_filter_aec);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kDAEchoCancellation,
-                             &options->delay_agnostic_aec);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kAutoGainControl,
-                             &options->auto_gain_control);
-  ConstraintToOptional<bool>(
-      constraints, MediaConstraintsInterface::kExperimentalAutoGainControl,
-      &options->experimental_agc);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kNoiseSuppression,
-                             &options->noise_suppression);
-  ConstraintToOptional<bool>(
-      constraints, MediaConstraintsInterface::kExperimentalNoiseSuppression,
-      &options->experimental_ns);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kHighpassFilter,
-                             &options->highpass_filter);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kTypingNoiseDetection,
-                             &options->typing_detection);
-  ConstraintToOptional<bool>(constraints,
-                             MediaConstraintsInterface::kAudioMirroring,
-                             &options->stereo_swapping);
-  ConstraintToOptional<std::string>(
-      constraints, MediaConstraintsInterface::kAudioNetworkAdaptorConfig,
-      &options->audio_network_adaptor_config);
-  // When |kAudioNetworkAdaptorConfig| is defined, it both means that audio
-  // network adaptor is desired, and provides the config string.
-  if (options->audio_network_adaptor_config) {
-    options->audio_network_adaptor = true;
-  }
-}
-
-bool CopyConstraintsIntoOfferAnswerOptions(
-    const MediaConstraintsInterface* constraints,
-    PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
-  if (!constraints) {
-    return true;
-  }
-
-  bool value = false;
-  size_t mandatory_constraints_satisfied = 0;
-
-  if (FindConstraint(constraints,
-                     MediaConstraintsInterface::kOfferToReceiveAudio, &value,
-                     &mandatory_constraints_satisfied)) {
-    offer_answer_options->offer_to_receive_audio =
-        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
-                    kOfferToReceiveMediaTrue
-              : 0;
-  }
-
-  if (FindConstraint(constraints,
-                     MediaConstraintsInterface::kOfferToReceiveVideo, &value,
-                     &mandatory_constraints_satisfied)) {
-    offer_answer_options->offer_to_receive_video =
-        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
-                    kOfferToReceiveMediaTrue
-              : 0;
-  }
-  if (FindConstraint(constraints,
-                     MediaConstraintsInterface::kVoiceActivityDetection, &value,
-                     &mandatory_constraints_satisfied)) {
-    offer_answer_options->voice_activity_detection = value;
-  }
-  if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
-                     &mandatory_constraints_satisfied)) {
-    offer_answer_options->use_rtp_mux = value;
-  }
-  if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
-                     &value, &mandatory_constraints_satisfied)) {
-    offer_answer_options->ice_restart = value;
-  }
-
-  int layers;
-  if (FindConstraint(constraints,
-                     MediaConstraintsInterface::kNumSimulcastLayers,
-                     &layers, &mandatory_constraints_satisfied)) {
-    offer_answer_options->num_simulcast_layers = layers;
-  }
-
-  return mandatory_constraints_satisfied == constraints->GetMandatory().size();
-}
-
-}  // namespace webrtc
diff --git a/api/test/fake_constraints.h b/api/test/fake_constraints.h
deleted file mode 100644
index 7080fb2..0000000
--- a/api/test/fake_constraints.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Copyright 2012 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.
- */
-
-#ifndef API_TEST_FAKE_CONSTRAINTS_H_
-#define API_TEST_FAKE_CONSTRAINTS_H_
-
-#include <string>
-#include <vector>
-
-#include "api/media_constraints_interface.h"
-#include "rtc_base/string_encode.h"
-
-namespace webrtc {
-
-class FakeConstraints : public webrtc::MediaConstraintsInterface {
- public:
-  FakeConstraints() {}
-  virtual ~FakeConstraints() {}
-
-  virtual const Constraints& GetMandatory() const { return mandatory_; }
-
-  virtual const Constraints& GetOptional() const { return optional_; }
-
-  template <class T>
-  void AddMandatory(const std::string& key, const T& value) {
-    mandatory_.push_back(Constraint(key, rtc::ToString(value)));
-  }
-
-  template <class T>
-  void SetMandatory(const std::string& key, const T& value) {
-    std::string value_str;
-    if (mandatory_.FindFirst(key, &value_str)) {
-      for (Constraints::iterator iter = mandatory_.begin();
-           iter != mandatory_.end(); ++iter) {
-        if (iter->key == key) {
-          mandatory_.erase(iter);
-          break;
-        }
-      }
-    }
-    mandatory_.push_back(Constraint(key, rtc::ToString(value)));
-  }
-
-  template <class T>
-  void AddOptional(const std::string& key, const T& value) {
-    optional_.push_back(Constraint(key, rtc::ToString(value)));
-  }
-
-  void SetMandatoryReceiveAudio(bool enable) {
-    SetMandatory(MediaConstraintsInterface::kOfferToReceiveAudio, enable);
-  }
-
-  void SetMandatoryReceiveVideo(bool enable) {
-    SetMandatory(MediaConstraintsInterface::kOfferToReceiveVideo, enable);
-  }
-
-  void SetMandatoryUseRtpMux(bool enable) {
-    SetMandatory(MediaConstraintsInterface::kUseRtpMux, enable);
-  }
-
-  void SetMandatoryIceRestart(bool enable) {
-    SetMandatory(MediaConstraintsInterface::kIceRestart, enable);
-  }
-
-  void SetAllowRtpDataChannels() {
-    SetMandatory(MediaConstraintsInterface::kEnableRtpDataChannels, true);
-    SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, false);
-  }
-
-  void SetOptionalVAD(bool enable) {
-    AddOptional(MediaConstraintsInterface::kVoiceActivityDetection, enable);
-  }
-
-  void SetAllowDtlsSctpDataChannels() {
-    SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, true);
-  }
-
- private:
-  Constraints mandatory_;
-  Constraints optional_;
-};
-
-}  // namespace webrtc
-
-#endif  // API_TEST_FAKE_CONSTRAINTS_H_
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 5e16e26..20bb5d2 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -415,7 +415,6 @@
       "../api:audio_options_api",
       "../api:create_peerconnection_factory",
       "../api:libjingle_peerconnection_api",
-      "../api:libjingle_peerconnection_test_api",
       "../api:rtc_stats_api",
       "../api:scoped_refptr",
       "../api/audio:audio_mixer_api",
@@ -462,7 +461,6 @@
       "ice_server_parsing_unittest.cc",
       "jsep_session_description_unittest.cc",
       "local_audio_source_unittest.cc",
-      "media_constraints_interface_unittest.cc",
       "media_stream_unittest.cc",
       "peer_connection_bundle_unittest.cc",
       "peer_connection_crypto_unittest.cc",
@@ -546,7 +544,6 @@
       "..:webrtc_common",
       "../api:callfactory_api",
       "../api:fake_media_transport",
-      "../api:libjingle_peerconnection_test_api",
       "../api:rtc_stats_api",
       "../api/audio_codecs:audio_codecs_api",
       "../api/audio_codecs:builtin_audio_decoder_factory",
diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc
index 638ffc6..a2852be 100644
--- a/pc/peer_connection_factory.cc
+++ b/pc/peer_connection_factory.cc
@@ -15,7 +15,6 @@
 
 #include "absl/memory/memory.h"
 #include "api/fec_controller.h"
-#include "api/media_constraints_interface.h"
 #include "api/media_stream_proxy.h"
 #include "api/media_stream_track_proxy.h"
 #include "api/media_transport_interface.h"
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 77d3c43..7963405 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -27,6 +27,29 @@
   }
 }
 
+rtc_source_set("media_constraints") {
+  sources = [
+    "media_constraints.cc",
+    "media_constraints.h",
+  ]
+  deps = [
+    "../api:audio_options_api",
+    "../api:libjingle_peerconnection_api",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
+rtc_source_set("sdk_tests") {
+  testonly = true
+  sources = [
+    "media_constraints_unittest.cc",
+  ]
+  deps = [
+    ":media_constraints",
+    "../test:test_support",
+  ]
+}
+
 if (is_ios || is_mac) {
   config("common_config_objc") {
     include_dirs = [
@@ -668,7 +691,7 @@
       deps = [
         ":base_objc",
         ":helpers_objc",
-        "../api:libjingle_peerconnection_api",
+        ":media_constraints",
       ]
     }
 
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index 0e603e4..79569a4 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -752,6 +752,7 @@
       ":logging_jni",
       ":native_api_jni",
       ":native_api_stacktrace",
+      "..:media_constraints",
       "../..:webrtc_common",
       "../../api:libjingle_peerconnection_api",
       "../../api/video_codecs:video_codecs_api",
diff --git a/sdk/android/src/jni/pc/media_constraints.cc b/sdk/android/src/jni/pc/media_constraints.cc
index 8c7d173..ed51266 100644
--- a/sdk/android/src/jni/pc/media_constraints.cc
+++ b/sdk/android/src/jni/pc/media_constraints.cc
@@ -21,10 +21,10 @@
 namespace {
 
 // Helper for translating a List<Pair<String, String>> to a Constraints.
-MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList(
+MediaConstraints::Constraints PopulateConstraintsFromJavaPairList(
     JNIEnv* env,
     const JavaRef<jobject>& j_list) {
-  MediaConstraintsInterface::Constraints constraints;
+  MediaConstraints::Constraints constraints;
   for (const JavaRef<jobject>& entry : Iterable(env, j_list)) {
     constraints.emplace_back(
         JavaToStdString(env, Java_KeyValuePair_getKey(env, entry)),
@@ -33,34 +33,17 @@
   return constraints;
 }
 
-// Wrapper for a Java MediaConstraints object.  Copies all needed data so when
-// the constructor returns the Java object is no longer needed.
-class MediaConstraintsJni : public MediaConstraintsInterface {
- public:
-  MediaConstraintsJni(JNIEnv* env, const JavaRef<jobject>& j_constraints)
-      : mandatory_(PopulateConstraintsFromJavaPairList(
-            env,
-            Java_MediaConstraints_getMandatory(env, j_constraints))),
-        optional_(PopulateConstraintsFromJavaPairList(
-            env,
-            Java_MediaConstraints_getOptional(env, j_constraints))) {}
-  ~MediaConstraintsJni() override = default;
-
-  // MediaConstraintsInterface.
-  const Constraints& GetMandatory() const override { return mandatory_; }
-  const Constraints& GetOptional() const override { return optional_; }
-
- private:
-  const Constraints mandatory_;
-  const Constraints optional_;
-};
-
 }  // namespace
 
-std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
+// Copies all needed data so Java object is no longer needed at return.
+std::unique_ptr<MediaConstraints> JavaToNativeMediaConstraints(
     JNIEnv* env,
     const JavaRef<jobject>& j_constraints) {
-  return absl::make_unique<MediaConstraintsJni>(env, j_constraints);
+  return absl::make_unique<MediaConstraints>(
+      PopulateConstraintsFromJavaPairList(
+          env, Java_MediaConstraints_getMandatory(env, j_constraints)),
+      PopulateConstraintsFromJavaPairList(
+          env, Java_MediaConstraints_getOptional(env, j_constraints)));
 }
 
 }  // namespace jni
diff --git a/sdk/android/src/jni/pc/media_constraints.h b/sdk/android/src/jni/pc/media_constraints.h
index e29b900..68cedc7 100644
--- a/sdk/android/src/jni/pc/media_constraints.h
+++ b/sdk/android/src/jni/pc/media_constraints.h
@@ -14,13 +14,13 @@
 #include <jni.h>
 #include <memory>
 
-#include "api/media_constraints_interface.h"
 #include "sdk/android/native_api/jni/scoped_java_ref.h"
+#include "sdk/media_constraints.h"
 
 namespace webrtc {
 namespace jni {
 
-std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
+std::unique_ptr<MediaConstraints> JavaToNativeMediaConstraints(
     JNIEnv* env,
     const JavaRef<jobject>& j_constraints);
 
diff --git a/sdk/android/src/jni/pc/peer_connection.cc b/sdk/android/src/jni/pc/peer_connection.cc
index 50a48c4..4d963b0 100644
--- a/sdk/android/src/jni/pc/peer_connection.cc
+++ b/sdk/android/src/jni/pc/peer_connection.cc
@@ -33,7 +33,6 @@
 #include <utility>
 
 #include "absl/memory/memory.h"
-#include "api/media_constraints_interface.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtp_receiver_interface.h"
 #include "api/rtp_sender_interface.h"
@@ -411,7 +410,7 @@
 OwnedPeerConnection::OwnedPeerConnection(
     rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
     std::unique_ptr<PeerConnectionObserver> observer,
-    std::unique_ptr<MediaConstraintsInterface> constraints)
+    std::unique_ptr<MediaConstraints> constraints)
     : peer_connection_(peer_connection),
       observer_(std::move(observer)),
       constraints_(std::move(constraints)) {}
@@ -482,7 +481,7 @@
     const JavaParamRef<jobject>& j_pc,
     const JavaParamRef<jobject>& j_observer,
     const JavaParamRef<jobject>& j_constraints) {
-  std::unique_ptr<MediaConstraintsInterface> constraints =
+  std::unique_ptr<MediaConstraints> constraints =
       JavaToNativeMediaConstraints(jni, j_constraints);
   rtc::scoped_refptr<CreateSdpObserverJni> observer(
       new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
@@ -497,7 +496,7 @@
     const JavaParamRef<jobject>& j_pc,
     const JavaParamRef<jobject>& j_observer,
     const JavaParamRef<jobject>& j_constraints) {
-  std::unique_ptr<MediaConstraintsInterface> constraints =
+  std::unique_ptr<MediaConstraints> constraints =
       JavaToNativeMediaConstraints(jni, j_constraints);
   rtc::scoped_refptr<CreateSdpObserverJni> observer(
       new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
diff --git a/sdk/android/src/jni/pc/peer_connection.h b/sdk/android/src/jni/pc/peer_connection.h
index 15465e4..91d4ef0 100644
--- a/sdk/android/src/jni/pc/peer_connection.h
+++ b/sdk/android/src/jni/pc/peer_connection.h
@@ -108,18 +108,16 @@
   OwnedPeerConnection(
       rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
       std::unique_ptr<PeerConnectionObserver> observer,
-      std::unique_ptr<MediaConstraintsInterface> constraints);
+      std::unique_ptr<MediaConstraints> constraints);
   ~OwnedPeerConnection();
 
   PeerConnectionInterface* pc() const { return peer_connection_.get(); }
-  const MediaConstraintsInterface* constraints() const {
-    return constraints_.get();
-  }
+  const MediaConstraints* constraints() const { return constraints_.get(); }
 
  private:
   rtc::scoped_refptr<PeerConnectionInterface> peer_connection_;
   std::unique_ptr<PeerConnectionObserver> observer_;
-  std::unique_ptr<MediaConstraintsInterface> constraints_;
+  std::unique_ptr<MediaConstraints> constraints_;
 };
 
 }  // namespace jni
diff --git a/sdk/android/src/jni/pc/peer_connection_factory.cc b/sdk/android/src/jni/pc/peer_connection_factory.cc
index 79ac732..00e207e 100644
--- a/sdk/android/src/jni/pc/peer_connection_factory.cc
+++ b/sdk/android/src/jni/pc/peer_connection_factory.cc
@@ -370,7 +370,7 @@
     JNIEnv* jni,
     jlong native_factory,
     const JavaParamRef<jobject>& j_constraints) {
-  std::unique_ptr<MediaConstraintsInterface> constraints =
+  std::unique_ptr<MediaConstraints> constraints =
       JavaToNativeMediaConstraints(jni, j_constraints);
   cricket::AudioOptions options;
   CopyConstraintsIntoAudioOptions(constraints.get(), &options);
@@ -437,7 +437,7 @@
     }
   }
 
-  std::unique_ptr<MediaConstraintsInterface> constraints;
+  std::unique_ptr<MediaConstraints> constraints;
   if (!j_constraints.is_null()) {
     constraints = JavaToNativeMediaConstraints(jni, j_constraints);
     CopyConstraintsIntoRtcConfiguration(constraints.get(), &rtc_config);
diff --git a/sdk/android/src/jni/pc/sdp_observer.cc b/sdk/android/src/jni/pc/sdp_observer.cc
index 47d13fa..78d345a 100644
--- a/sdk/android/src/jni/pc/sdp_observer.cc
+++ b/sdk/android/src/jni/pc/sdp_observer.cc
@@ -12,10 +12,10 @@
 
 #include <utility>
 
-#include "api/media_constraints_interface.h"
 #include "sdk/android/generated_peerconnection_jni/jni/SdpObserver_jni.h"
 #include "sdk/android/native_api/jni/java_types.h"
 #include "sdk/android/src/jni/jni_helpers.h"
+#include "sdk/media_constraints.h"
 
 namespace webrtc {
 namespace jni {
@@ -23,7 +23,7 @@
 CreateSdpObserverJni::CreateSdpObserverJni(
     JNIEnv* env,
     const JavaRef<jobject>& j_observer,
-    std::unique_ptr<MediaConstraintsInterface> constraints)
+    std::unique_ptr<MediaConstraints> constraints)
     : j_observer_global_(env, j_observer),
       constraints_(std::move(constraints)) {}
 
@@ -47,7 +47,7 @@
 SetSdpObserverJni::SetSdpObserverJni(
     JNIEnv* env,
     const JavaRef<jobject>& j_observer,
-    std::unique_ptr<MediaConstraintsInterface> constraints)
+    std::unique_ptr<MediaConstraints> constraints)
     : j_observer_global_(env, j_observer),
       constraints_(std::move(constraints)) {}
 
diff --git a/sdk/android/src/jni/pc/sdp_observer.h b/sdk/android/src/jni/pc/sdp_observer.h
index 9a7a4d9..68ded76 100644
--- a/sdk/android/src/jni/pc/sdp_observer.h
+++ b/sdk/android/src/jni/pc/sdp_observer.h
@@ -14,10 +14,10 @@
 #include <memory>
 #include <string>
 
-#include "api/media_constraints_interface.h"
 #include "api/peer_connection_interface.h"
 #include "sdk/android/src/jni/jni_helpers.h"
 #include "sdk/android/src/jni/pc/session_description.h"
+#include "sdk/media_constraints.h"
 
 namespace webrtc {
 namespace jni {
@@ -26,34 +26,34 @@
  public:
   CreateSdpObserverJni(JNIEnv* env,
                        const JavaRef<jobject>& j_observer,
-                       std::unique_ptr<MediaConstraintsInterface> constraints);
+                       std::unique_ptr<MediaConstraints> constraints);
   ~CreateSdpObserverJni() override;
 
-  MediaConstraintsInterface* constraints() { return constraints_.get(); }
+  MediaConstraints* constraints() { return constraints_.get(); }
 
   void OnSuccess(SessionDescriptionInterface* desc) override;
   void OnFailure(RTCError error) override;
 
  private:
   const ScopedJavaGlobalRef<jobject> j_observer_global_;
-  std::unique_ptr<MediaConstraintsInterface> constraints_;
+  std::unique_ptr<MediaConstraints> constraints_;
 };
 
 class SetSdpObserverJni : public SetSessionDescriptionObserver {
  public:
   SetSdpObserverJni(JNIEnv* env,
                     const JavaRef<jobject>& j_observer,
-                    std::unique_ptr<MediaConstraintsInterface> constraints);
+                    std::unique_ptr<MediaConstraints> constraints);
   ~SetSdpObserverJni() override;
 
-  MediaConstraintsInterface* constraints() { return constraints_.get(); }
+  MediaConstraints* constraints() { return constraints_.get(); }
 
   void OnSuccess() override;
   void OnFailure(RTCError error) override;
 
  private:
   const ScopedJavaGlobalRef<jobject> j_observer_global_;
-  std::unique_ptr<MediaConstraintsInterface> constraints_;
+  std::unique_ptr<MediaConstraints> constraints_;
 };
 
 }  // namespace jni
diff --git a/sdk/media_constraints.cc b/sdk/media_constraints.cc
new file mode 100644
index 0000000..7c5fe4a
--- /dev/null
+++ b/sdk/media_constraints.cc
@@ -0,0 +1,274 @@
+/*
+ *  Copyright 2013 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 "sdk/media_constraints.h"
+
+#include "absl/types/optional.h"
+#include "api/peer_connection_interface.h"
+
+namespace webrtc {
+namespace {
+
+// Find the highest-priority instance of the T-valued constraint named by
+// |key| and return its value as |value|. |constraints| can be null.
+// If |mandatory_constraints| is non-null, it is incremented if the key appears
+// among the mandatory constraints.
+// Returns true if the key was found and has a valid value for type T.
+// If the key appears multiple times as an optional constraint, appearances
+// after the first are ignored.
+// Note: Because this uses FindFirst, repeated optional constraints whose
+// first instance has an unrecognized value are not handled precisely in
+// accordance with the specification.
+template <typename T>
+bool FindConstraint(const MediaConstraints* constraints,
+                    const std::string& key,
+                    T* value,
+                    size_t* mandatory_constraints) {
+  std::string string_value;
+  if (!FindConstraint(constraints, key, &string_value, mandatory_constraints)) {
+    return false;
+  }
+  return rtc::FromString(string_value, value);
+}
+
+// Specialization for std::string, since a string doesn't need conversion.
+template <>
+bool FindConstraint(const MediaConstraints* constraints,
+                    const std::string& key,
+                    std::string* value,
+                    size_t* mandatory_constraints) {
+  if (!constraints) {
+    return false;
+  }
+  if (constraints->GetMandatory().FindFirst(key, value)) {
+    if (mandatory_constraints) {
+      ++*mandatory_constraints;
+    }
+    return true;
+  }
+  if (constraints->GetOptional().FindFirst(key, value)) {
+    return true;
+  }
+  return false;
+}
+
+bool FindConstraint(const MediaConstraints* constraints,
+                    const std::string& key,
+                    bool* value,
+                    size_t* mandatory_constraints) {
+  return FindConstraint<bool>(constraints, key, value, mandatory_constraints);
+}
+
+bool FindConstraint(const MediaConstraints* constraints,
+                    const std::string& key,
+                    int* value,
+                    size_t* mandatory_constraints) {
+  return FindConstraint<int>(constraints, key, value, mandatory_constraints);
+}
+
+// Converts a constraint (mandatory takes precedence over optional) to an
+// absl::optional.
+template <typename T>
+void ConstraintToOptional(const MediaConstraints* constraints,
+                          const std::string& key,
+                          absl::optional<T>* value_out) {
+  T value;
+  bool present = FindConstraint<T>(constraints, key, &value, nullptr);
+  if (present) {
+    *value_out = value;
+  }
+}
+}  // namespace
+
+const char MediaConstraints::kValueTrue[] = "true";
+const char MediaConstraints::kValueFalse[] = "false";
+
+// Constraints declared as static members in mediastreaminterface.h
+
+// Audio constraints.
+const char MediaConstraints::kGoogEchoCancellation[] = "googEchoCancellation";
+const char MediaConstraints::kExtendedFilterEchoCancellation[] =
+    "googEchoCancellation2";
+const char MediaConstraints::kDAEchoCancellation[] = "googDAEchoCancellation";
+const char MediaConstraints::kAutoGainControl[] = "googAutoGainControl";
+const char MediaConstraints::kExperimentalAutoGainControl[] =
+    "googAutoGainControl2";
+const char MediaConstraints::kNoiseSuppression[] = "googNoiseSuppression";
+const char MediaConstraints::kExperimentalNoiseSuppression[] =
+    "googNoiseSuppression2";
+const char MediaConstraints::kHighpassFilter[] = "googHighpassFilter";
+const char MediaConstraints::kTypingNoiseDetection[] =
+    "googTypingNoiseDetection";
+const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
+const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
+    "googAudioNetworkAdaptorConfig";
+
+// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
+const char MediaConstraints::kOfferToReceiveAudio[] = "OfferToReceiveAudio";
+const char MediaConstraints::kOfferToReceiveVideo[] = "OfferToReceiveVideo";
+const char MediaConstraints::kVoiceActivityDetection[] =
+    "VoiceActivityDetection";
+const char MediaConstraints::kIceRestart[] = "IceRestart";
+// Google specific constraint for BUNDLE enable/disable.
+const char MediaConstraints::kUseRtpMux[] = "googUseRtpMUX";
+
+// Below constraints should be used during PeerConnection construction.
+const char MediaConstraints::kEnableDtlsSrtp[] = "DtlsSrtpKeyAgreement";
+const char MediaConstraints::kEnableRtpDataChannels[] = "RtpDataChannels";
+// Google-specific constraint keys.
+const char MediaConstraints::kEnableDscp[] = "googDscp";
+const char MediaConstraints::kEnableIPv6[] = "googIPv6";
+const char MediaConstraints::kEnableVideoSuspendBelowMinBitrate[] =
+    "googSuspendBelowMinBitrate";
+const char MediaConstraints::kCombinedAudioVideoBwe[] =
+    "googCombinedAudioVideoBwe";
+const char MediaConstraints::kScreencastMinBitrate[] =
+    "googScreencastMinBitrate";
+// TODO(ronghuawu): Remove once cpu overuse detection is stable.
+const char MediaConstraints::kCpuOveruseDetection[] = "googCpuOveruseDetection";
+
+const char MediaConstraints::kNumSimulcastLayers[] = "googNumSimulcastLayers";
+
+// Set |value| to the value associated with the first appearance of |key|, or
+// return false if |key| is not found.
+bool MediaConstraints::Constraints::FindFirst(const std::string& key,
+                                              std::string* value) const {
+  for (Constraints::const_iterator iter = begin(); iter != end(); ++iter) {
+    if (iter->key == key) {
+      *value = iter->value;
+      return true;
+    }
+  }
+  return false;
+}
+
+void CopyConstraintsIntoRtcConfiguration(
+    const MediaConstraints* constraints,
+    PeerConnectionInterface::RTCConfiguration* configuration) {
+  // Copy info from constraints into configuration, if present.
+  if (!constraints) {
+    return;
+  }
+
+  bool enable_ipv6;
+  if (FindConstraint(constraints, MediaConstraints::kEnableIPv6, &enable_ipv6,
+                     nullptr)) {
+    configuration->disable_ipv6 = !enable_ipv6;
+  }
+  FindConstraint(constraints, MediaConstraints::kEnableDscp,
+                 &configuration->media_config.enable_dscp, nullptr);
+  FindConstraint(constraints, MediaConstraints::kCpuOveruseDetection,
+                 &configuration->media_config.video.enable_cpu_adaptation,
+                 nullptr);
+  FindConstraint(constraints, MediaConstraints::kEnableRtpDataChannels,
+                 &configuration->enable_rtp_data_channel, nullptr);
+  // Find Suspend Below Min Bitrate constraint.
+  FindConstraint(
+      constraints, MediaConstraints::kEnableVideoSuspendBelowMinBitrate,
+      &configuration->media_config.video.suspend_below_min_bitrate, nullptr);
+  ConstraintToOptional<int>(constraints,
+                            MediaConstraints::kScreencastMinBitrate,
+                            &configuration->screencast_min_bitrate);
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kCombinedAudioVideoBwe,
+                             &configuration->combined_audio_video_bwe);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kEnableDtlsSrtp,
+                             &configuration->enable_dtls_srtp);
+}
+
+void CopyConstraintsIntoAudioOptions(const MediaConstraints* constraints,
+                                     cricket::AudioOptions* options) {
+  if (!constraints) {
+    return;
+  }
+
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kGoogEchoCancellation,
+                             &options->echo_cancellation);
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kExtendedFilterEchoCancellation,
+                             &options->extended_filter_aec);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kDAEchoCancellation,
+                             &options->delay_agnostic_aec);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kAutoGainControl,
+                             &options->auto_gain_control);
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kExperimentalAutoGainControl,
+                             &options->experimental_agc);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kNoiseSuppression,
+                             &options->noise_suppression);
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kExperimentalNoiseSuppression,
+                             &options->experimental_ns);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kHighpassFilter,
+                             &options->highpass_filter);
+  ConstraintToOptional<bool>(constraints,
+                             MediaConstraints::kTypingNoiseDetection,
+                             &options->typing_detection);
+  ConstraintToOptional<bool>(constraints, MediaConstraints::kAudioMirroring,
+                             &options->stereo_swapping);
+  ConstraintToOptional<std::string>(
+      constraints, MediaConstraints::kAudioNetworkAdaptorConfig,
+      &options->audio_network_adaptor_config);
+  // When |kAudioNetworkAdaptorConfig| is defined, it both means that audio
+  // network adaptor is desired, and provides the config string.
+  if (options->audio_network_adaptor_config) {
+    options->audio_network_adaptor = true;
+  }
+}
+
+bool CopyConstraintsIntoOfferAnswerOptions(
+    const MediaConstraints* constraints,
+    PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
+  if (!constraints) {
+    return true;
+  }
+
+  bool value = false;
+  size_t mandatory_constraints_satisfied = 0;
+
+  if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveAudio,
+                     &value, &mandatory_constraints_satisfied)) {
+    offer_answer_options->offer_to_receive_audio =
+        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+                    kOfferToReceiveMediaTrue
+              : 0;
+  }
+
+  if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveVideo,
+                     &value, &mandatory_constraints_satisfied)) {
+    offer_answer_options->offer_to_receive_video =
+        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+                    kOfferToReceiveMediaTrue
+              : 0;
+  }
+  if (FindConstraint(constraints, MediaConstraints::kVoiceActivityDetection,
+                     &value, &mandatory_constraints_satisfied)) {
+    offer_answer_options->voice_activity_detection = value;
+  }
+  if (FindConstraint(constraints, MediaConstraints::kUseRtpMux, &value,
+                     &mandatory_constraints_satisfied)) {
+    offer_answer_options->use_rtp_mux = value;
+  }
+  if (FindConstraint(constraints, MediaConstraints::kIceRestart, &value,
+                     &mandatory_constraints_satisfied)) {
+    offer_answer_options->ice_restart = value;
+  }
+
+  int layers;
+  if (FindConstraint(constraints, MediaConstraints::kNumSimulcastLayers,
+                     &layers, &mandatory_constraints_satisfied)) {
+    offer_answer_options->num_simulcast_layers = layers;
+  }
+
+  return mandatory_constraints_satisfied == constraints->GetMandatory().size();
+}
+
+}  // namespace webrtc
diff --git a/api/media_constraints_interface.h b/sdk/media_constraints.h
similarity index 76%
rename from api/media_constraints_interface.h
rename to sdk/media_constraints.h
index adfa2b5..3a15141 100644
--- a/api/media_constraints_interface.h
+++ b/sdk/media_constraints.h
@@ -8,21 +8,17 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-// This file contains the interface for MediaConstraints, corresponding to
-// the definition at
-// http://www.w3.org/TR/mediacapture-streams/#mediastreamconstraints and also
-// used in WebRTC: http://dev.w3.org/2011/webrtc/editor/webrtc.html#constraints.
-
 // Implementation of the w3c constraints spec is the responsibility of the
 // browser. Chrome no longer uses the constraints api declared here, and it will
 // be removed from WebRTC.
 // https://bugs.chromium.org/p/webrtc/issues/detail?id=9239
 
-#ifndef API_MEDIA_CONSTRAINTS_INTERFACE_H_
-#define API_MEDIA_CONSTRAINTS_INTERFACE_H_
+#ifndef SDK_MEDIA_CONSTRAINTS_H_
+#define SDK_MEDIA_CONSTRAINTS_H_
 
 #include <stddef.h>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "api/audio_options.h"
@@ -30,13 +26,12 @@
 
 namespace webrtc {
 
-// Interface used for passing arguments about media constraints
-// to the MediaStream and PeerConnection implementation.
+// Class representing constraints, as used by the android and objc apis.
 //
 // Constraints may be either "mandatory", which means that unless satisfied,
 // the method taking the constraints should fail, or "optional", which means
 // they may not be satisfied..
-class MediaConstraintsInterface {
+class MediaConstraints {
  public:
   struct Constraint {
     Constraint() {}
@@ -48,9 +43,17 @@
 
   class Constraints : public std::vector<Constraint> {
    public:
+    Constraints() = default;
+    Constraints(std::initializer_list<Constraint> l)
+        : std::vector<Constraint>(l) {}
+
     bool FindFirst(const std::string& key, std::string* value) const;
   };
 
+  MediaConstraints() = default;
+  MediaConstraints(Constraints mandatory, Constraints optional)
+      : mandatory_(std::move(mandatory)), optional_(std::move(optional)) {}
+
   // Constraint keys used by a local audio source.
 
   // These keys are google specific.
@@ -104,36 +107,29 @@
   // (see RTCOfferAnswerOptions::num_simulcast_layers).
   static const char kNumSimulcastLayers[];
 
-  virtual ~MediaConstraintsInterface() = default;
+  ~MediaConstraints() = default;
 
-  virtual const Constraints& GetMandatory() const = 0;
-  virtual const Constraints& GetOptional() const = 0;
+  const Constraints& GetMandatory() const { return mandatory_; }
+  const Constraints& GetOptional() const { return optional_; }
+
+ private:
+  const Constraints mandatory_ = {};
+  const Constraints optional_ = {};
 };
 
-bool FindConstraint(const MediaConstraintsInterface* constraints,
-                    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,
+    const MediaConstraints* constraints,
     PeerConnectionInterface::RTCConfiguration* configuration);
 
 // Copy all relevant constraints into an AudioOptions object.
-void CopyConstraintsIntoAudioOptions(
-    const MediaConstraintsInterface* constraints,
-    cricket::AudioOptions* options);
+void CopyConstraintsIntoAudioOptions(const MediaConstraints* constraints,
+                                     cricket::AudioOptions* options);
 
 bool CopyConstraintsIntoOfferAnswerOptions(
-    const MediaConstraintsInterface* constraints,
+    const MediaConstraints* constraints,
     PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options);
 
 }  // namespace webrtc
 
-#endif  // API_MEDIA_CONSTRAINTS_INTERFACE_H_
+#endif  // SDK_MEDIA_CONSTRAINTS_H_
diff --git a/pc/media_constraints_interface_unittest.cc b/sdk/media_constraints_unittest.cc
similarity index 65%
rename from pc/media_constraints_interface_unittest.cc
rename to sdk/media_constraints_unittest.cc
index b62e092..7fd7f67 100644
--- a/pc/media_constraints_interface_unittest.cc
+++ b/sdk/media_constraints_unittest.cc
@@ -8,11 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "api/media_constraints_interface.h"
+#include "sdk/media_constraints.h"
 
-#include "absl/types/optional.h"
-#include "api/test/fake_constraints.h"
-#include "media/base/media_config.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -33,34 +30,40 @@
          a.media_config == b.media_config;
 }
 
-TEST(MediaConstraintsInterface, CopyConstraintsIntoRtcConfiguration) {
-  FakeConstraints constraints;
+TEST(MediaConstraints, CopyConstraintsIntoRtcConfiguration) {
+  const MediaConstraints constraints_empty;
   PeerConnectionInterface::RTCConfiguration old_configuration;
   PeerConnectionInterface::RTCConfiguration configuration;
 
-  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  CopyConstraintsIntoRtcConfiguration(&constraints_empty, &configuration);
   EXPECT_TRUE(Matches(old_configuration, configuration));
 
-  constraints.SetMandatory(MediaConstraintsInterface::kEnableIPv6, "true");
-  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  const MediaConstraints constraits_enable_ipv6(
+      {MediaConstraints::Constraint(MediaConstraints::kEnableIPv6, "true")},
+      {});
+  CopyConstraintsIntoRtcConfiguration(&constraits_enable_ipv6, &configuration);
   EXPECT_FALSE(configuration.disable_ipv6);
-  constraints.SetMandatory(MediaConstraintsInterface::kEnableIPv6, "false");
-  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  const MediaConstraints constraints_disable_ipv6(
+      {MediaConstraints::Constraint(MediaConstraints::kEnableIPv6, "false")},
+      {});
+  CopyConstraintsIntoRtcConfiguration(&constraints_disable_ipv6,
+                                      &configuration);
   EXPECT_TRUE(configuration.disable_ipv6);
 
-  constraints.SetMandatory(MediaConstraintsInterface::kScreencastMinBitrate,
-                           27);
-  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  const MediaConstraints constraints_screencast(
+      {MediaConstraints::Constraint(MediaConstraints::kScreencastMinBitrate,
+                                    "27")},
+      {});
+  CopyConstraintsIntoRtcConfiguration(&constraints_screencast, &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 = true;
   configuration.audio_jitter_buffer_max_packets = 34;
-  CopyConstraintsIntoRtcConfiguration(&constraints, &configuration);
+  CopyConstraintsIntoRtcConfiguration(&constraints_empty, &configuration);
   EXPECT_EQ(34, configuration.audio_jitter_buffer_max_packets);
   ASSERT_TRUE(configuration.enable_dtls_srtp);
   EXPECT_TRUE(*(configuration.enable_dtls_srtp));
diff --git a/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h b/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h
index 335b029..b3e1b10 100644
--- a/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h
+++ b/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h
@@ -12,25 +12,7 @@
 
 #include <memory>
 
-#include "api/media_constraints_interface.h"
-
-namespace webrtc {
-
-class MediaConstraints : public MediaConstraintsInterface {
- public:
-  ~MediaConstraints() override;
-  MediaConstraints();
-  MediaConstraints(const MediaConstraintsInterface::Constraints& mandatory,
-                   const MediaConstraintsInterface::Constraints& optional);
-  const Constraints& GetMandatory() const override;
-  const Constraints& GetOptional() const override;
-
- private:
-  MediaConstraintsInterface::Constraints mandatory_;
-  MediaConstraintsInterface::Constraints optional_;
-};
-
-}  // namespace webrtc
+#include "sdk/media_constraints.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -43,8 +25,8 @@
 - (std::unique_ptr<webrtc::MediaConstraints>)nativeConstraints;
 
 /** Return a native Constraints object representing these constraints */
-+ (webrtc::MediaConstraintsInterface::Constraints)nativeConstraintsForConstraints:
-        (NSDictionary<NSString*, NSString*>*)constraints;
++ (webrtc::MediaConstraints::Constraints)nativeConstraintsForConstraints:
+    (NSDictionary<NSString*, NSString*>*)constraints;
 
 @end
 
diff --git a/sdk/objc/api/peerconnection/RTCMediaConstraints.mm b/sdk/objc/api/peerconnection/RTCMediaConstraints.mm
index 0a6b9d8..bfdbdde 100644
--- a/sdk/objc/api/peerconnection/RTCMediaConstraints.mm
+++ b/sdk/objc/api/peerconnection/RTCMediaConstraints.mm
@@ -14,46 +14,19 @@
 
 #include <memory>
 
-NSString * const kRTCMediaConstraintsAudioNetworkAdaptorConfig =
-    @(webrtc::MediaConstraintsInterface::kAudioNetworkAdaptorConfig);
+NSString *const kRTCMediaConstraintsAudioNetworkAdaptorConfig =
+    @(webrtc::MediaConstraints::kAudioNetworkAdaptorConfig);
 
-NSString * const kRTCMediaConstraintsIceRestart =
-    @(webrtc::MediaConstraintsInterface::kIceRestart);
-NSString * const kRTCMediaConstraintsOfferToReceiveAudio =
-    @(webrtc::MediaConstraintsInterface::kOfferToReceiveAudio);
-NSString * const kRTCMediaConstraintsOfferToReceiveVideo =
-    @(webrtc::MediaConstraintsInterface::kOfferToReceiveVideo);
-NSString * const kRTCMediaConstraintsVoiceActivityDetection =
-    @(webrtc::MediaConstraintsInterface::kVoiceActivityDetection);
+NSString *const kRTCMediaConstraintsIceRestart = @(webrtc::MediaConstraints::kIceRestart);
+NSString *const kRTCMediaConstraintsOfferToReceiveAudio =
+    @(webrtc::MediaConstraints::kOfferToReceiveAudio);
+NSString *const kRTCMediaConstraintsOfferToReceiveVideo =
+    @(webrtc::MediaConstraints::kOfferToReceiveVideo);
+NSString *const kRTCMediaConstraintsVoiceActivityDetection =
+    @(webrtc::MediaConstraints::kVoiceActivityDetection);
 
-NSString * const kRTCMediaConstraintsValueTrue =
-    @(webrtc::MediaConstraintsInterface::kValueTrue);
-NSString * const kRTCMediaConstraintsValueFalse =
-    @(webrtc::MediaConstraintsInterface::kValueFalse);
-
-namespace webrtc {
-
-MediaConstraints::~MediaConstraints() {}
-
-MediaConstraints::MediaConstraints() {}
-
-MediaConstraints::MediaConstraints(
-    const MediaConstraintsInterface::Constraints& mandatory,
-    const MediaConstraintsInterface::Constraints& optional)
-    : mandatory_(mandatory), optional_(optional) {}
-
-const MediaConstraintsInterface::Constraints&
-MediaConstraints::GetMandatory() const {
-  return mandatory_;
-}
-
-const MediaConstraintsInterface::Constraints&
-MediaConstraints::GetOptional() const {
-  return optional_;
-}
-
-}  // namespace webrtc
-
+NSString *const kRTCMediaConstraintsValueTrue = @(webrtc::MediaConstraints::kValueTrue);
+NSString *const kRTCMediaConstraintsValueFalse = @(webrtc::MediaConstraints::kValueFalse);
 
 @implementation RTCMediaConstraints {
   NSDictionary<NSString *, NSString *> *_mandatory;
@@ -82,9 +55,9 @@
 #pragma mark - Private
 
 - (std::unique_ptr<webrtc::MediaConstraints>)nativeConstraints {
-  webrtc::MediaConstraintsInterface::Constraints mandatory =
+  webrtc::MediaConstraints::Constraints mandatory =
       [[self class] nativeConstraintsForConstraints:_mandatory];
-  webrtc::MediaConstraintsInterface::Constraints optional =
+  webrtc::MediaConstraints::Constraints optional =
       [[self class] nativeConstraintsForConstraints:_optional];
 
   webrtc::MediaConstraints *nativeConstraints =
@@ -92,10 +65,9 @@
   return std::unique_ptr<webrtc::MediaConstraints>(nativeConstraints);
 }
 
-+ (webrtc::MediaConstraintsInterface::Constraints)
-    nativeConstraintsForConstraints:
-        (NSDictionary<NSString *, NSString *> *)constraints {
-  webrtc::MediaConstraintsInterface::Constraints nativeConstraints;
++ (webrtc::MediaConstraints::Constraints)nativeConstraintsForConstraints:
+    (NSDictionary<NSString *, NSString *> *)constraints {
+  webrtc::MediaConstraints::Constraints nativeConstraints;
   for (NSString *key in constraints) {
     NSAssert([key isKindOfClass:[NSString class]],
              @"%@ is not an NSString.", key);
@@ -107,11 +79,10 @@
       NSData *charData = [[NSData alloc] initWithBase64EncodedString:value options:0];
       std::string configValue =
           std::string(reinterpret_cast<const char *>(charData.bytes), charData.length);
-      nativeConstraints.push_back(webrtc::MediaConstraintsInterface::Constraint(
-          key.stdString, configValue));
+      nativeConstraints.push_back(webrtc::MediaConstraints::Constraint(key.stdString, configValue));
     } else {
-      nativeConstraints.push_back(webrtc::MediaConstraintsInterface::Constraint(
-          key.stdString, value.stdString));
+      nativeConstraints.push_back(
+          webrtc::MediaConstraints::Constraint(key.stdString, value.stdString));
     }
   }
   return nativeConstraints;
diff --git a/sdk/objc/unittests/RTCMediaConstraintsTest.mm b/sdk/objc/unittests/RTCMediaConstraintsTest.mm
index f50149d..4d5e450 100644
--- a/sdk/objc/unittests/RTCMediaConstraintsTest.mm
+++ b/sdk/objc/unittests/RTCMediaConstraintsTest.mm
@@ -34,18 +34,15 @@
   std::unique_ptr<webrtc::MediaConstraints> nativeConstraints =
       [constraints nativeConstraints];
 
-  webrtc::MediaConstraintsInterface::Constraints nativeMandatory =
-      nativeConstraints->GetMandatory();
+  webrtc::MediaConstraints::Constraints nativeMandatory = nativeConstraints->GetMandatory();
   [self expectConstraints:mandatory inNativeConstraints:nativeMandatory];
 
-  webrtc::MediaConstraintsInterface::Constraints nativeOptional =
-      nativeConstraints->GetOptional();
+  webrtc::MediaConstraints::Constraints nativeOptional = nativeConstraints->GetOptional();
   [self expectConstraints:optional inNativeConstraints:nativeOptional];
 }
 
 - (void)expectConstraints:(NSDictionary *)constraints
-      inNativeConstraints:
-    (webrtc::MediaConstraintsInterface::Constraints)nativeConstraints {
+      inNativeConstraints:(webrtc::MediaConstraints::Constraints)nativeConstraints {
   EXPECT_EQ(constraints.count, nativeConstraints.size());
 
   for (NSString *key in constraints) {