Backed out changeset 85832c026282 (bug 1213517)
authorIris Hsiao <ihsiao@mozilla.com>
Mon, 18 Jul 2016 15:40:03 +0800
changeset 347386 91beab01e7859b24b32f796c28dc3b736c4324d4
parent 347385 0067bcf60359c2b2571ed860c0c1f54db20a0455
child 347387 1adb5905697d107fab50193ca93ecf340e72349d
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1213517
milestone50.0a1
backs out85832c026282b6047faa6d36330aba7ba3d74115
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 85832c026282 (bug 1213517)
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/webrtc/MediaEngine.h
dom/media/webrtc/MediaEngineCameraVideoSource.cpp
dom/media/webrtc/MediaEngineCameraVideoSource.h
dom/media/webrtc/MediaEngineDefault.cpp
dom/media/webrtc/MediaEngineDefault.h
dom/media/webrtc/MediaEngineTabVideoSource.h
dom/media/webrtc/MediaEngineWebRTC.h
dom/media/webrtc/MediaEngineWebRTCAudio.cpp
dom/media/webrtc/MediaTrackConstraints.cpp
dom/media/webrtc/MediaTrackConstraints.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -781,30 +781,31 @@ MediaDevice::FitnessDistance(nsString aN
     params.mIdeal.Construct();
     params.mIdeal.Value().SetAsStringSequence() = aConstraint.GetAsStringSequence();
     return FitnessDistance(aN, params);
   } else {
     return FitnessDistance(aN, aConstraint.GetAsConstrainDOMStringParameters());
   }
 }
 
+// Reminder: add handling for new constraints both here and in GetSources below!
+
 uint32_t
 MediaDevice::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets)
+    const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
 {
   nsString mediaSource;
   GetMediaSource(mediaSource);
 
   // This code is reused for audio, where the mediaSource constraint does
   // not currently have a function, but because it defaults to "camera" in
   // webidl, we ignore it for audio here.
   if (!mediaSource.EqualsASCII("microphone")) {
     for (const auto& constraint : aConstraintSets) {
-      if (constraint->mMediaSource.mIdeal.find(mediaSource) ==
-          constraint->mMediaSource.mIdeal.end()) {
+      if (mediaSource != constraint->mMediaSource) {
         return UINT32_MAX;
       }
     }
   }
   // Forward request to underlying object to interrogate per-mode capabilities.
   // Pass in device's origin-specific id for deviceId constraint comparison.
   nsString id;
   GetId(id);
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -65,17 +65,17 @@ class MediaDevice : public nsIMediaDevic
 public:
   typedef MediaEngineSource Source;
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIMEDIADEVICE
 
   void SetId(const nsAString& aID);
   virtual uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets);
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets);
   virtual Source* GetSource() = 0;
   nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
                     const MediaEnginePrefs &aPrefs,
                     const nsACString& aOrigin,
                     const char** aOutBadConstraint);
   nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
                    const MediaEnginePrefs &aPrefs,
                    const char** aOutBadConstraint);
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -189,17 +189,17 @@ public:
   virtual nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
                             const MediaEnginePrefs &aPrefs,
                             const nsString& aDeviceId,
                             const nsACString& aOrigin,
                             BaseAllocationHandle** aOutHandle,
                             const char** aOutBadConstraint) = 0;
 
   virtual uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) = 0;
 
 protected:
   // Only class' own members can be initialized in constructor initializer list.
   explicit MediaEngineSource(MediaEngineState aState)
     : mState(aState)
 #ifdef DEBUG
     , mOwningThread(PR_GetCurrentThread())
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -98,33 +98,34 @@ MediaEngineCameraVideoSource::TrimLessFi
 // Ideal values are considered in the first ConstraintSet only.
 // Plain values are treated as Ideal in the first ConstraintSet.
 // Plain values are treated as Exact in subsequent ConstraintSets.
 // Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
 // A finite result may be used to calculate this device's ranking as a choice.
 
 uint32_t
 MediaEngineCameraVideoSource::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   size_t num = NumCapabilities();
 
   CapabilitySet candidateSet;
   for (size_t i = 0; i < num; i++) {
     candidateSet.AppendElement(i);
   }
 
   bool first = true;
-  for (const NormalizedConstraintSet* ns : aConstraintSets) {
+  for (const MediaTrackConstraintSet* cs : aConstraintSets) {
+    NormalizedConstraintSet ns(*cs, !first);
     for (size_t i = 0; i < candidateSet.Length();  ) {
       auto& candidate = candidateSet[i];
       webrtc::CaptureCapability cap;
       GetCapability(candidate.mIndex, cap);
-      uint32_t distance = GetFitnessDistance(cap, *ns, aDeviceId);
+      uint32_t distance = GetFitnessDistance(cap, ns, aDeviceId);
       if (distance == UINT32_MAX) {
         candidateSet.RemoveElementAt(i);
       } else {
         ++i;
         if (first) {
           candidate.mDistance = distance;
         }
       }
@@ -239,21 +240,16 @@ MediaEngineCameraVideoSource::ChooseCapa
     LogCapability("Capability", cap, candidate.mDistance);
     if (candidate.mDistance == UINT32_MAX) {
       candidateSet.RemoveElementAt(i);
     } else {
       ++i;
     }
   }
 
-  if (!candidateSet.Length()) {
-    LOG(("failed to find capability match from %d choices",num));
-    return false;
-  }
-
   // Filter further with all advanced constraints (that don't overconstrain).
 
   for (const auto &cs : aConstraints.mAdvanced) {
     CapabilitySet rejects;
     for (size_t i = 0; i < candidateSet.Length();) {
       auto& candidate = candidateSet[i];
       webrtc::CaptureCapability cap;
       GetCapability(candidate.mIndex, cap);
@@ -263,18 +259,20 @@ MediaEngineCameraVideoSource::ChooseCapa
       } else {
         ++i;
       }
     }
     if (!candidateSet.Length()) {
       candidateSet.AppendElements(Move(rejects));
     }
   }
-  MOZ_ASSERT(candidateSet.Length(),
-             "advanced constraints filtering step can't reduce candidates to zero");
+  if (!candidateSet.Length()) {
+    LOG(("failed to find capability match from %d choices",num));
+    return false;
+  }
 
   // Remaining algorithm is up to the UA.
 
   TrimLessFitCandidates(candidateSet);
 
   // Any remaining multiples all have the same distance. A common case of this
   // occurs when no ideal is specified. Lean toward defaults.
   uint32_t sameDistance = candidateSet[0].mDistance;
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -44,17 +44,17 @@ public:
   }
 
   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) override;
 
   void Shutdown() override {};
 
 protected:
   struct CapabilityCandidate {
     explicit CapabilityCandidate(uint8_t index, uint32_t distance = 0)
     : mIndex(index), mDistance(distance) {}
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -67,23 +67,23 @@ void
 MediaEngineDefaultVideoSource::GetUUID(nsACString& aUUID)
 {
   aUUID.AssignLiteral("1041FCBD-3F12-4F7B-9E9B-1EC556DD5676");
   return;
 }
 
 uint32_t
 MediaEngineDefaultVideoSource::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   uint32_t distance = 0;
 #ifdef MOZ_WEBRTC
-  for (const auto* cs : aConstraintSets) {
-    distance = GetMinimumFitnessDistance(*cs, aDeviceId);
+  for (const dom::MediaTrackConstraintSet* cs : aConstraintSets) {
+    distance = GetMinimumFitnessDistance(*cs, false, aDeviceId);
     break; // distance is read from first entry only
   }
 #endif
   return distance;
 }
 
 nsresult
 MediaEngineDefaultVideoSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
@@ -395,23 +395,23 @@ void
 MediaEngineDefaultAudioSource::GetUUID(nsACString& aUUID)
 {
   aUUID.AssignLiteral("B7CBD7C1-53EF-42F9-8353-73F61C70C092");
   return;
 }
 
 uint32_t
 MediaEngineDefaultAudioSource::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   uint32_t distance = 0;
 #ifdef MOZ_WEBRTC
-  for (const auto* cs : aConstraintSets) {
-    distance = GetMinimumFitnessDistance(*cs, aDeviceId);
+  for (const dom::MediaTrackConstraintSet* cs : aConstraintSets) {
+    distance = GetMinimumFitnessDistance(*cs, false, aDeviceId);
     break; // distance is read from first entry only
   }
 #endif
   return distance;
 }
 
 nsresult
 MediaEngineDefaultAudioSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
--- a/dom/media/webrtc/MediaEngineDefault.h
+++ b/dom/media/webrtc/MediaEngineDefault.h
@@ -60,17 +60,17 @@ public:
                    const char** aOutBadConstraint) override;
   void SetDirectListeners(bool aHasDirectListeners) override {};
   void NotifyPull(MediaStreamGraph* aGraph,
                   SourceMediaStream *aSource,
                   TrackID aId,
                   StreamTime aDesiredTime,
                   const PrincipalHandle& aPrincipalHandle) override;
   uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) override;
 
   bool IsFake() override {
     return true;
   }
 
   dom::MediaSourceEnum GetMediaSource() const override {
     return dom::MediaSourceEnum::Camera;
@@ -169,17 +169,17 @@ public:
   }
 
   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) override;
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
 protected:
   ~MediaEngineDefaultAudioSource();
 
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -38,17 +38,17 @@ class MediaEngineTabVideoSource : public
                      const mozilla::MediaEnginePrefs& aPrefs,
                      const nsString& aDeviceId,
                      const char** aOutBadConstraint) override;
     bool IsFake() override;
     dom::MediaSourceEnum GetMediaSource() const override {
       return dom::MediaSourceEnum::Browser;
     }
     uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) override
     {
       return 0;
     }
 
     nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
     {
       return NS_ERROR_NOT_IMPLEMENTED;
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -130,17 +130,17 @@ public:
   {
     return false;
   }
   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   uint32_t GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId) override;
 
 protected:
   virtual ~MediaEngineWebRTCAudioCaptureSource() { Shutdown(); }
   nsCString mUUID;
 };
 
 // Small subset of VoEHardware
@@ -497,17 +497,17 @@ public:
   }
 
   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   uint32_t GetBestFitnessDistance(
-      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+      const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) override;
 
   // VoEMediaProcess.
   void Process(int channel, webrtc::ProcessingTypes type,
                int16_t audio10ms[], int length,
                int samplingFreq, bool isStereo) override;
 
   void Shutdown() override;
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -201,23 +201,23 @@ MediaEngineWebRTCMicrophoneSource::GetUU
 // as a whole, given an accumulated number of ConstraintSets.
 // Ideal values are considered in the first ConstraintSet only.
 // Plain values are treated as Ideal in the first ConstraintSet.
 // Plain values are treated as Exact in subsequent ConstraintSets.
 // Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
 // A finite result may be used to calculate this device's ranking as a choice.
 
 uint32_t MediaEngineWebRTCMicrophoneSource::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   uint32_t distance = 0;
 
-  for (const auto* cs : aConstraintSets) {
-    distance = GetMinimumFitnessDistance(*cs, aDeviceId);
+  for (const MediaTrackConstraintSet* cs : aConstraintSets) {
+    distance = GetMinimumFitnessDistance(*cs, false, aDeviceId);
     break; // distance is read from first entry only
   }
   return distance;
 }
 
 nsresult
 MediaEngineWebRTCMicrophoneSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
                                             const MediaEnginePrefs &aPrefs,
@@ -854,16 +854,16 @@ MediaEngineWebRTCAudioCaptureSource::Res
     const char** aOutBadConstraint)
 {
   MOZ_ASSERT(!aHandle);
   return NS_OK;
 }
 
 uint32_t
 MediaEngineWebRTCAudioCaptureSource::GetBestFitnessDistance(
-    const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
+    const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   // There is only one way of capturing audio for now, and it's always adequate.
   return 0;
 }
 
 }
--- a/dom/media/webrtc/MediaTrackConstraints.cpp
+++ b/dom/media/webrtc/MediaTrackConstraints.cpp
@@ -350,20 +350,23 @@ FlattenedConstraints::FlattenedConstrain
 //
 // Fitness distance returned as integer math * 1000. Infinity = UINT32_MAX
 
 // First, all devices have a minimum distance based on their deviceId.
 // If you have no other constraints, use this one. Reused by all device types.
 
 uint32_t
 MediaConstraintsHelper::GetMinimumFitnessDistance(
-    const NormalizedConstraintSet &aConstraints,
+    const dom::MediaTrackConstraintSet &aConstraints,
+    bool aAdvanced,
     const nsString& aDeviceId)
 {
-  return FitnessDistance(aDeviceId, aConstraints.mDeviceId);
+  NormalizedConstraintSet ns(aConstraints, aAdvanced);
+
+  return FitnessDistance(aDeviceId, ns.mDeviceId);
 }
 
 template<class ValueType, class NormalizedRange>
 /* static */ uint32_t
 MediaConstraintsHelper::FitnessDistance(ValueType aN,
                                         const NormalizedRange& aRange)
 {
   if (aRange.mMin > aN || aRange.mMax < aN) {
--- a/dom/media/webrtc/MediaTrackConstraints.h
+++ b/dom/media/webrtc/MediaTrackConstraints.h
@@ -246,18 +246,18 @@ public:
 };
 
 template<> bool NormalizedConstraintSet::Range<bool>::Merge(const Range& aOther);
 template<> void NormalizedConstraintSet::Range<bool>::FinalizeMerge();
 
 // Used instead of MediaTrackConstraints in lower-level code.
 struct NormalizedConstraints : public NormalizedConstraintSet
 {
-  NormalizedConstraints(const dom::MediaTrackConstraints& aOther,
-                        nsTArray<MemberPtrType>* aList = nullptr);
+  explicit NormalizedConstraints(const dom::MediaTrackConstraints& aOther,
+                                 nsTArray<MemberPtrType>* aList = nullptr);
 
   // Merge constructor
   explicit NormalizedConstraints(
       const nsTArray<const NormalizedConstraints*>& aOthers);
 
   nsTArray<NormalizedConstraintSet> mAdvanced;
   const char* mBadConstraint;
 };
@@ -277,148 +277,143 @@ class MediaConstraintsHelper
 {
 protected:
   template<class ValueType, class NormalizedRange>
   static uint32_t FitnessDistance(ValueType aN, const NormalizedRange& aRange);
   static uint32_t FitnessDistance(nsString aN,
       const NormalizedConstraintSet::StringRange& aConstraint);
 
   static uint32_t
-  GetMinimumFitnessDistance(const NormalizedConstraintSet &aConstraints,
+  GetMinimumFitnessDistance(const dom::MediaTrackConstraintSet &aConstraints,
+                            bool aAdvanced,
                             const nsString& aDeviceId);
 
   template<class DeviceType>
   static bool
-  SomeSettingsFit(const NormalizedConstraints &aConstraints,
+  SomeSettingsFit(const dom::MediaTrackConstraints &aConstraints,
                   nsTArray<RefPtr<DeviceType>>& aSources)
   {
-    nsTArray<const NormalizedConstraintSet*> sets;
-    sets.AppendElement(&aConstraints);
+    nsTArray<const dom::MediaTrackConstraintSet*> aggregateConstraints;
+    aggregateConstraints.AppendElement(&aConstraints);
 
     MOZ_ASSERT(aSources.Length());
     for (auto& source : aSources) {
-      if (source->GetBestFitnessDistance(sets) != UINT32_MAX) {
+      if (source->GetBestFitnessDistance(aggregateConstraints) != UINT32_MAX) {
         return true;
       }
     }
     return false;
   }
 
 public:
   // Apply constrains to a supplied list of sources (removes items from the list)
 
   template<class DeviceType>
   static const char*
-  SelectSettings(const NormalizedConstraints &aConstraints,
+  SelectSettings(const dom::MediaTrackConstraints &aConstraints,
                  nsTArray<RefPtr<DeviceType>>& aSources)
   {
     auto& c = aConstraints;
 
     // First apply top-level constraints.
 
     // Stack constraintSets that pass, starting with the required one, because the
     // whole stack must be re-satisfied each time a capability-set is ruled out
     // (this avoids storing state or pushing algorithm into the lower-level code).
     nsTArray<RefPtr<DeviceType>> unsatisfactory;
-    nsTArray<const NormalizedConstraintSet*> aggregateConstraints;
+    nsTArray<const dom::MediaTrackConstraintSet*> aggregateConstraints;
     aggregateConstraints.AppendElement(&c);
 
     std::multimap<uint32_t, RefPtr<DeviceType>> ordered;
 
     for (uint32_t i = 0; i < aSources.Length();) {
       uint32_t distance = aSources[i]->GetBestFitnessDistance(aggregateConstraints);
       if (distance == UINT32_MAX) {
         unsatisfactory.AppendElement(aSources[i]);
         aSources.RemoveElementAt(i);
       } else {
         ordered.insert(std::pair<uint32_t, RefPtr<DeviceType>>(distance,
                                                                  aSources[i]));
         ++i;
       }
     }
     if (!aSources.Length()) {
-      return FindBadConstraint(c, unsatisfactory);
+      // None selected. The spec says to report a constraint that satisfies NONE
+      // of the sources. Unfortunately, this is a bit laborious to find out, and
+      // requires updating as new constraints are added!
+
+      if (!unsatisfactory.Length() ||
+          !SomeSettingsFit(dom::MediaTrackConstraints(), unsatisfactory)) {
+        return "";
+      }
+      if (c.mDeviceId.IsConstrainDOMStringParameters()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mDeviceId = c.mDeviceId;
+        if (!SomeSettingsFit(fresh, unsatisfactory)) {
+          return "deviceId";
+        }
+      }
+      if (c.mWidth.IsConstrainLongRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mWidth = c.mWidth;
+        if (!SomeSettingsFit(fresh, unsatisfactory)) {
+          return "width";
+        }
+      }
+      if (c.mHeight.IsConstrainLongRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mHeight = c.mHeight;
+        if (!SomeSettingsFit(fresh, unsatisfactory)) {
+          return "height";
+        }
+      }
+      if (c.mFrameRate.IsConstrainDoubleRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mFrameRate = c.mFrameRate;
+        if (!SomeSettingsFit(fresh, unsatisfactory)) {
+          return "frameRate";
+        }
+      }
+      if (c.mFacingMode.IsConstrainDOMStringParameters()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mFacingMode = c.mFacingMode;
+        if (!SomeSettingsFit(fresh, unsatisfactory)) {
+          return "facingMode";
+        }
+      }
+      return "";
     }
 
     // Order devices by shortest distance
     for (auto& ordinal : ordered) {
       aSources.RemoveElement(ordinal.second);
       aSources.AppendElement(ordinal.second);
     }
 
     // Then apply advanced constraints.
 
-    for (int i = 0; i < int(c.mAdvanced.Length()); i++) {
-      aggregateConstraints.AppendElement(&c.mAdvanced[i]);
-      nsTArray<RefPtr<DeviceType>> rejects;
-      for (uint32_t j = 0; j < aSources.Length();) {
-        if (aSources[j]->GetBestFitnessDistance(aggregateConstraints) == UINT32_MAX) {
-          rejects.AppendElement(aSources[j]);
-          aSources.RemoveElementAt(j);
-        } else {
-          ++j;
+    if (c.mAdvanced.WasPassed()) {
+      auto &array = c.mAdvanced.Value();
+
+      for (int i = 0; i < int(array.Length()); i++) {
+        aggregateConstraints.AppendElement(&array[i]);
+        nsTArray<RefPtr<DeviceType>> rejects;
+        for (uint32_t j = 0; j < aSources.Length();) {
+          if (aSources[j]->GetBestFitnessDistance(aggregateConstraints) == UINT32_MAX) {
+            rejects.AppendElement(aSources[j]);
+            aSources.RemoveElementAt(j);
+          } else {
+            ++j;
+          }
         }
-      }
-      if (!aSources.Length()) {
-        aSources.AppendElements(Move(rejects));
-        aggregateConstraints.RemoveElementAt(aggregateConstraints.Length() - 1);
+        if (!aSources.Length()) {
+          aSources.AppendElements(Move(rejects));
+          aggregateConstraints.RemoveElementAt(aggregateConstraints.Length() - 1);
+        }
       }
     }
     return nullptr;
   }
-
-  template<class DeviceType>
-  static const char*
-  FindBadConstraint(const NormalizedConstraints& aConstraints,
-                    nsTArray<RefPtr<DeviceType>>& aSources)
-  {
-    // The spec says to report a constraint that satisfies NONE
-    // of the sources. Unfortunately, this is a bit laborious to find out, and
-    // requires updating as new constraints are added!
-    auto& c = aConstraints;
-    dom::MediaTrackConstraints empty;
-
-    if (!aSources.Length() ||
-        !SomeSettingsFit(NormalizedConstraints(empty), aSources)) {
-      return "";
-    }
-    {
-      NormalizedConstraints fresh(empty);
-      fresh.mDeviceId = c.mDeviceId;
-      if (!SomeSettingsFit(fresh, aSources)) {
-        return "deviceId";
-      }
-    }
-    {
-      NormalizedConstraints fresh(empty);
-      fresh.mWidth = c.mWidth;
-      if (!SomeSettingsFit(fresh, aSources)) {
-        return "width";
-      }
-    }
-    {
-      NormalizedConstraints fresh(empty);
-      fresh.mHeight = c.mHeight;
-      if (!SomeSettingsFit(fresh, aSources)) {
-        return "height";
-      }
-    }
-    {
-      NormalizedConstraints fresh(empty);
-      fresh.mFrameRate = c.mFrameRate;
-      if (!SomeSettingsFit(fresh, aSources)) {
-        return "frameRate";
-      }
-    }
-    {
-      NormalizedConstraints fresh(empty);
-      fresh.mFacingMode = c.mFacingMode;
-      if (!SomeSettingsFit(fresh, aSources)) {
-        return "facingMode";
-      }
-    }
-    return "";
-  }
 };
 
 } // namespace mozilla
 
 #endif /* MEDIATRACKCONSTRAINTS_H_ */