From 412a6bc6ff0128c3b069fdd1e14964064b114d4f Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Fri, 18 Apr 2014 14:00:16 -0400 Subject: [PATCH] Bug 907352 - Part 1: Update to most recent constraints syntax. r=mt --- .../recognition/SpeechRecognition.cpp | 4 +- dom/base/Navigator.cpp | 7 +- dom/base/Navigator.h | 6 +- dom/media/GetUserMediaRequest.cpp | 6 +- dom/media/GetUserMediaRequest.h | 8 +- dom/media/MediaManager.cpp | 263 +++++++++--------- dom/media/MediaManager.h | 4 +- dom/media/MediaPermissionGonk.cpp | 4 +- .../test_getUserMedia_constraints.html | 46 ++- .../test_getUserMedia_exceptions.html | 2 +- dom/webidl/GetUserMediaRequest.webidl | 2 +- dom/webidl/MediaStream.webidl | 11 +- dom/webidl/MediaStreamTrack.webidl | 32 +-- dom/webidl/Navigator.webidl | 2 +- 14 files changed, 205 insertions(+), 192 deletions(-) diff --git a/content/media/webspeech/recognition/SpeechRecognition.cpp b/content/media/webspeech/recognition/SpeechRecognition.cpp index f397a496de66..b41160f4754e 100644 --- a/content/media/webspeech/recognition/SpeechRecognition.cpp +++ b/content/media/webspeech/recognition/SpeechRecognition.cpp @@ -711,14 +711,12 @@ SpeechRecognition::Start(ErrorResult& aRv) rv = mRecognitionService->Initialize(this->asWeakPtr()); NS_ENSURE_SUCCESS_VOID(rv); - AutoSafeJSContext cx; MediaStreamConstraints constraints; constraints.mAudio.SetAsBoolean() = true; if (!mTestConfig.mFakeFSMEvents) { MediaManager* manager = MediaManager::Get(); - manager->GetUserMedia(cx, - false, + manager->GetUserMedia(false, GetOwner(), constraints, new GetUserMediaSuccessCallback(this), diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 6db67067e2a0..7ac36c43279d 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1294,8 +1294,7 @@ Navigator::SendBeacon(const nsAString& aUrl, #ifdef MOZ_MEDIA_NAVIGATOR void -Navigator::MozGetUserMedia(JSContext* aCx, - const MediaStreamConstraints& aConstraints, +Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints, NavigatorUserMediaSuccessCallback& aOnSuccess, NavigatorUserMediaErrorCallback& aOnError, ErrorResult& aRv) @@ -1318,12 +1317,12 @@ Navigator::MozGetUserMedia(JSContext* aCx, bool privileged = nsContentUtils::IsChromeDoc(mWindow->GetExtantDoc()); MediaManager* manager = MediaManager::Get(); - aRv = manager->GetUserMedia(aCx, privileged, mWindow, aConstraints, + aRv = manager->GetUserMedia(privileged, mWindow, aConstraints, onsuccess, onerror); } void -Navigator::MozGetUserMediaDevices(const MediaStreamConstraintsInternal& aConstraints, +Navigator::MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints, MozGetUserMediaDevicesSuccessCallback& aOnSuccess, NavigatorUserMediaErrorCallback& aOnError, uint64_t aInnerWindowID, diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index b1a8990b6436..a4cbf42bdded 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -33,7 +33,6 @@ namespace dom { class Geolocation; class systemMessageCallback; class MediaStreamConstraints; -class MediaStreamConstraintsInternal; class WakeLock; class ArrayBufferViewOrBlobOrStringOrFormData; } @@ -231,12 +230,11 @@ public: ErrorResult& aRv); #ifdef MOZ_MEDIA_NAVIGATOR - void MozGetUserMedia(JSContext* aCx, - const MediaStreamConstraints& aConstraints, + void MozGetUserMedia(const MediaStreamConstraints& aConstraints, NavigatorUserMediaSuccessCallback& aOnSuccess, NavigatorUserMediaErrorCallback& aOnError, ErrorResult& aRv); - void MozGetUserMediaDevices(const MediaStreamConstraintsInternal& aConstraints, + void MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints, MozGetUserMediaDevicesSuccessCallback& aOnSuccess, NavigatorUserMediaErrorCallback& aOnError, uint64_t aInnerWindowID, diff --git a/dom/media/GetUserMediaRequest.cpp b/dom/media/GetUserMediaRequest.cpp index c0c320240513..f0e8b9ca58a7 100644 --- a/dom/media/GetUserMediaRequest.cpp +++ b/dom/media/GetUserMediaRequest.cpp @@ -16,12 +16,12 @@ namespace dom { GetUserMediaRequest::GetUserMediaRequest( nsPIDOMWindow* aInnerWindow, const nsAString& aCallID, - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, bool aIsSecure) : mInnerWindowID(aInnerWindow->WindowID()) , mOuterWindowID(aInnerWindow->GetOuterWindow()->WindowID()) , mCallID(aCallID) - , mConstraints(new MediaStreamConstraintsInternal(aConstraints)) + , mConstraints(new MediaStreamConstraints(aConstraints)) , mIsSecure(aIsSecure) { SetIsDOMBinding(); @@ -67,7 +67,7 @@ bool GetUserMediaRequest::IsSecure() } void -GetUserMediaRequest::GetConstraints(MediaStreamConstraintsInternal &result) +GetUserMediaRequest::GetConstraints(MediaStreamConstraints &result) { result = *mConstraints; } diff --git a/dom/media/GetUserMediaRequest.h b/dom/media/GetUserMediaRequest.h index 0393fe51bbdc..6c5482c37e45 100644 --- a/dom/media/GetUserMediaRequest.h +++ b/dom/media/GetUserMediaRequest.h @@ -14,14 +14,14 @@ namespace mozilla { namespace dom { -class MediaStreamConstraintsInternal; +class MediaStreamConstraints; class GetUserMediaRequest : public nsISupports, public nsWrapperCache { public: GetUserMediaRequest(nsPIDOMWindow* aInnerWindow, const nsAString& aCallID, - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, bool aIsSecure); virtual ~GetUserMediaRequest() {}; @@ -36,12 +36,12 @@ public: uint64_t InnerWindowID(); bool IsSecure(); void GetCallID(nsString& retval); - void GetConstraints(MediaStreamConstraintsInternal &result); + void GetConstraints(MediaStreamConstraints &result); private: uint64_t mInnerWindowID, mOuterWindowID; const nsString mCallID; - nsAutoPtr mConstraints; + nsAutoPtr mConstraints; bool mIsSecure; }; diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index ecbcc4f84391..31a9ce1140e7 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -23,6 +23,7 @@ #include "nsIDocument.h" #include "nsISupportsPrimitives.h" #include "nsIInterfaceRequestorUtils.h" +#include "mozilla/Types.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/MediaStreamBinding.h" #include "mozilla/dom/MediaStreamTrackBinding.h" @@ -74,53 +75,11 @@ GetMediaManagerLog() #endif using dom::MediaStreamConstraints; // Outside API (contains JSObject) -using dom::MediaStreamConstraintsInternal; // Storable supported constraints -using dom::MediaTrackConstraintsInternal; // Video or audio constraints using dom::MediaTrackConstraintSet; // Mandatory or optional constraints using dom::MediaTrackConstraints; // Raw mMandatory (as JSObject) using dom::GetUserMediaRequest; using dom::Sequence; -using dom::OwningBooleanOrMediaTrackConstraintsInternal; - -// Used to compare raw MediaTrackConstraintSet against normalized dictionary -// version to detect member differences, e.g. unsupported constraints. - -static nsresult CompareDictionaries(JSContext* aCx, JSObject *aA, - const MediaTrackConstraintSet &aB, - nsString *aDifference) -{ - JS::Rooted a(aCx, aA); - JSAutoCompartment ac(aCx, aA); - JS::Rooted bval(aCx); - aB.ToObject(aCx, &bval); - JS::Rooted b(aCx, &bval.toObject()); - - // Iterate over each property in A, and check if it is in B - - JS::AutoIdArray props(aCx, JS_Enumerate(aCx, a)); - - for (size_t i = 0; i < props.length(); i++) { - JS::Rooted bprop(aCx); - JS::Rooted id(aCx, props[i]); - if (!JS_GetPropertyById(aCx, b, id, &bprop)) { - LOG(("Error parsing dictionary!\n")); - return NS_ERROR_UNEXPECTED; - } - if (bprop.isUndefined()) { - // Unknown property found in A. Bail with name - JS::Rooted nameval(aCx); - bool success = JS_IdToValue(aCx, props[i], &nameval); - NS_ENSURE_TRUE(success, NS_ERROR_UNEXPECTED); - - JS::Rooted namestr(aCx, JS::ToString(aCx, nameval)); - NS_ENSURE_TRUE(namestr, NS_ERROR_UNEXPECTED); - aDifference->Assign(JS_GetStringCharsZ(aCx, namestr)); - return NS_OK; - } - } - aDifference->Truncate(); - return NS_OK; -} +using dom::OwningBooleanOrMediaTrackConstraints; ErrorCallbackRunnable::ErrorCallbackRunnable( nsCOMPtr& aSuccess, @@ -680,25 +639,34 @@ private: }; static bool -IsOn(const dom::OwningBooleanOrMediaTrackConstraintsInternal &aUnion) { +IsOn(const dom::OwningBooleanOrMediaTrackConstraints &aUnion) { return !aUnion.IsBoolean() || aUnion.GetAsBoolean(); } -static JSObject * -GetMandatoryJSObj(const dom::OwningBooleanOrMediaTrackConstraints &aUnion) { - return (aUnion.IsMediaTrackConstraints() && - aUnion.GetAsMediaTrackConstraints().mMandatory.WasPassed()) ? - aUnion.GetAsMediaTrackConstraints().mMandatory.Value() : nullptr; -} - /** * Helper functions that implement the constraints algorithm from * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5 */ -static bool SatisfyConstraint(const MediaEngineVideoSource *, - const MediaTrackConstraintSet &aConstraints, - nsIMediaDevice &aCandidate) +#define lengthof(a) (sizeof(a) / sizeof(*a)) + +static auto +GetSupportedConstraintNames(const MediaEngineVideoSource *) -> + decltype((dom::SupportedVideoConstraintsValues::strings)) { + return dom::SupportedVideoConstraintsValues::strings; +} + +static auto +GetSupportedConstraintNames(const MediaEngineAudioSource *) -> + decltype((dom::SupportedAudioConstraintsValues::strings)) { + return dom::SupportedAudioConstraintsValues::strings; +} + +// Reminder: add handling for new constraints both here and in GetSources below! + +static bool SatisfyConstraintSet(const MediaEngineVideoSource *, + const MediaTrackConstraintSet &aConstraints, + nsIMediaDevice &aCandidate) { if (aConstraints.mFacingMode.WasPassed()) { nsString s; @@ -712,14 +680,42 @@ static bool SatisfyConstraint(const MediaEngineVideoSource *, return true; } -static bool SatisfyConstraint(const MediaEngineAudioSource *, - const MediaTrackConstraintSet &aConstraints, - nsIMediaDevice &aCandidate) +static bool SatisfyConstraintSet(const MediaEngineAudioSource *, + const MediaTrackConstraintSet &aConstraints, + nsIMediaDevice &aCandidate) { // TODO: Add audio-specific constraints return true; } +// Triage constraints into required and nonrequired + detect missing requireds + +class TriageHelper +{ +public: + TriageHelper(const nsTArray& aRequire) + : mRequire(aRequire) + , mNumRequirementsMet(0) {} + + MediaTrackConstraintSet& Triage(const nsAString &name) { + if (mRequire.IndexOf(name) != mRequire.NoIndex) { + mNumRequirementsMet++; + return mRequired; + } else { + return mNonrequired; + } + } + bool RequirementsAreMet() { + MOZ_ASSERT(mNumRequirementsMet <= mRequire.Length()); + return mNumRequirementsMet == mRequire.Length(); + } + MediaTrackConstraintSet mRequired; + MediaTrackConstraintSet mNonrequired; +private: + const nsTArray mRequire; + uint32_t mNumRequirementsMet; +}; + typedef nsTArray > SourceSet; // Source getter that constrains list returned @@ -727,7 +723,7 @@ typedef nsTArray > SourceSet; template static SourceSet * GetSources(MediaEngine *engine, - const OwningBooleanOrMediaTrackConstraintsInternal &aConstraints, + const OwningBooleanOrMediaTrackConstraints &aConstraints, void (MediaEngine::* aEnumerate)(nsTArray >*), char* media_device_name = nullptr) { @@ -767,24 +763,69 @@ static SourceSet * } } + // If unconstrained then return the full list. + if (aConstraints.IsBoolean()) { MOZ_ASSERT(aConstraints.GetAsBoolean()); result->MoveElementsFrom(candidateSet); return result.forget(); } - auto& constraints = aConstraints.GetAsMediaTrackConstraintsInternal(); - // Then apply mandatory constraints + // Otherwise apply constraints to the list of sources. - // Note: Iterator must be signed as it can dip below zero - for (int i = 0; i < int(candidateSet.Length()); i++) { - // Overloading instead of template specialization keeps things local - if (!SatisfyConstraint(type, constraints.mMandatory, *candidateSet[i])) { - candidateSet.RemoveElementAt(i--); + auto& constraints = aConstraints.GetAsMediaTrackConstraints(); + const nsTArray empty; + const auto &require = constraints.mRequire.WasPassed()? + constraints.mRequire.Value() : empty; + { + // Check upfront the names of required constraints that are unsupported for + // this media-type. The spec requires these to fail, so getting them out of + // the way early provides a necessary invariant for the remaining algorithm + // which maximizes code-reuse by ignoring constraints of the other type + // (specifically, SatisfyConstraintSet is reused for the advanced algorithm + // where the spec requires it to ignore constraints of the other type) + + const auto& supported = GetSupportedConstraintNames(type); + for (uint32_t i = 0; i < require.Length(); i++) { + bool found = false; + // EnumType arrays have a zero-terminator entry at the end. Skip. + for (size_t j = 0; j < sizeof(supported)/sizeof(*supported) - 1; j++) { + if (require[i].EqualsASCII(supported[j].value)) { + found = true; + break; + } + } + if (!found) { + return result.forget(); + } } } - // Then apply optional constraints. + // Before we start, triage constraints into required and nonrequired. + // Reminder: add handling for new constraints both here & SatisfyConstraintSet + + TriageHelper helper(require); + + if (constraints.mFacingMode.WasPassed()) { + helper.Triage(NS_LITERAL_STRING("facingMode")).mFacingMode.Construct( + constraints.mFacingMode.Value()); + } + if (!helper.RequirementsAreMet()) { + return result.forget(); + } + + // Now on to the actual algorithm: First apply required constraints. + + for (uint32_t i = 0; i < candidateSet.Length();) { + // Overloading instead of template specialization keeps things local + if (!SatisfyConstraintSet(type, helper.mRequired, *candidateSet[i])) { + candidateSet.RemoveElementAt(i); + } else { + ++i; + } + } + + // Then apply advanced (formerly known as optional) constraints. // // These are only effective when there are multiple sources to pick from. // Spec as-of-this-writing says to run algorithm on "all possible tracks @@ -800,21 +841,26 @@ static SourceSet * SourceSet tailSet; - if (constraints.mOptional.WasPassed()) { - const auto &array = constraints.mOptional.Value(); + if (constraints.mAdvanced.WasPassed()) { + const auto &array = constraints.mAdvanced.Value(); for (int i = 0; i < int(array.Length()); i++) { SourceSet rejects; - // Note: Iterator must be signed as it can dip below zero - for (int j = 0; j < int(candidateSet.Length()); j++) { - if (!SatisfyConstraint(type, array[i], *candidateSet[j])) { + for (uint32_t j = 0; j < candidateSet.Length();) { + if (!SatisfyConstraintSet(type, array[i], *candidateSet[j])) { rejects.AppendElement(candidateSet[j]); - candidateSet.RemoveElementAt(j--); + candidateSet.RemoveElementAt(j); + } else { + ++j; } } (candidateSet.Length()? tailSet : candidateSet).MoveElementsFrom(rejects); } } + // Finally, order any remaining sources by how many nonrequired constraints + // they satisfy. TODO(jib): TBD once we implement >1 constraint (Bug 907352) + + result->MoveElementsFrom(candidateSet); result->MoveElementsFrom(tailSet); return result.forget(); @@ -833,7 +879,7 @@ class GetUserMediaRunnable : public nsRunnable { public: GetUserMediaRunnable( - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, already_AddRefed aSuccess, already_AddRefed aError, uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener, @@ -854,7 +900,7 @@ public: * using the one provided by MediaManager::GetBackend. */ GetUserMediaRunnable( - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, already_AddRefed aSuccess, already_AddRefed aError, uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener, @@ -960,7 +1006,7 @@ public: } nsresult - SetContraints(const MediaStreamConstraintsInternal& aConstraints) + SetContraints(const MediaStreamConstraints& aConstraints) { mConstraints = aConstraints; return NS_OK; @@ -1089,7 +1135,7 @@ public: } private: - MediaStreamConstraintsInternal mConstraints; + MediaStreamConstraints mConstraints; nsCOMPtr mSuccess; nsCOMPtr mError; @@ -1115,7 +1161,7 @@ class GetUserMediaDevicesRunnable : public nsRunnable { public: GetUserMediaDevicesRunnable( - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, already_AddRefed aSuccess, already_AddRefed aError, uint64_t aWindowId, char* aAudioLoopbackDev, char* aVideoLoopbackDev) @@ -1156,7 +1202,7 @@ public: } private: - MediaStreamConstraintsInternal mConstraints; + MediaStreamConstraints mConstraints; nsCOMPtr mSuccess; nsCOMPtr mError; nsRefPtr mManager; @@ -1302,8 +1348,8 @@ MediaManager::NotifyRecordingStatusChange(nsPIDOMWindow* aWindow, * for handling all incoming getUserMedia calls from every window. */ nsresult -MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, - nsPIDOMWindow* aWindow, const MediaStreamConstraints& aRawConstraints, +MediaManager::GetUserMedia(bool aPrivileged, + nsPIDOMWindow* aWindow, const MediaStreamConstraints& aConstraints, nsIDOMGetUserMediaSuccessCallback* aOnSuccess, nsIDOMGetUserMediaErrorCallback* aOnError) { @@ -1316,42 +1362,6 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, nsCOMPtr onSuccess(aOnSuccess); nsCOMPtr onError(aOnError); - Maybe ac; - JS::Rooted audioObj (aCx, GetMandatoryJSObj(aRawConstraints.mAudio)); - JS::Rooted videoObj (aCx, GetMandatoryJSObj(aRawConstraints.mVideo)); - if (audioObj || videoObj) { - ac.construct(aCx, audioObj? audioObj : videoObj); - } - - // aRawConstraints may have JSObject in mMandatory, so copy everything into - // MediaStreamConstraintsInternal which does not. - - dom::RootedDictionary c(aCx); - JS::Rooted temp(aCx); - // This isn't the fastest way to copy a MediaStreamConstraints into a - // MediaStreamConstraintsInternal, but requires less code maintenance than an - // explicit member-by-member copy, and should be safe given the circumstances. - aRawConstraints.ToObject(aCx, &temp); - bool success = c.Init(aCx, temp); - NS_ENSURE_TRUE(success, NS_ERROR_FAILURE); - - // Validate mandatory constraints by detecting any unknown constraints. - // Done by comparing the raw MediaTrackConstraints against the normalized copy - - nsString unknownConstraintFound; - if (audioObj) { - nsresult rv = CompareDictionaries(aCx, audioObj, - c.mAudio.GetAsMediaTrackConstraintsInternal().mMandatory, - &unknownConstraintFound); - NS_ENSURE_SUCCESS(rv, rv); - } - if (videoObj) { - nsresult rv = CompareDictionaries(aCx, videoObj, - c.mVideo.GetAsMediaTrackConstraintsInternal().mMandatory, - &unknownConstraintFound); - NS_ENSURE_SUCCESS(rv, rv); - } - /** * If we were asked to get a picture, before getting a snapshot, we check if * the calling page is allowed to open a popup. We do this because @@ -1402,23 +1412,6 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, GetActiveWindows()->Put(windowID, listeners); } - if (!unknownConstraintFound.IsEmpty()) { - // An unsupported mandatory constraint was found. - // - // We continue to ignore these for now, because we implement just - // facingMode, which means all existing uses of mandatory width/height would - // fail on Firefox only otherwise, which is undesirable. - // - // There's also basis for always ignoring them in a new proposal. - // TODO(jib): This is a super-low-risk fix for backport. Clean up later. - - LOG(("Unsupported mandatory constraint: %s\n", - NS_ConvertUTF16toUTF8(unknownConstraintFound).get())); - - // unknown constraints existed in aRawConstraints only, which is unused - // from here, so continuing here effectively ignores them, as is desired. - } - // Ensure there's a thread for gum to proxy to off main thread nsIThread *mediaThread = MediaManager::GetThread(); @@ -1429,6 +1422,8 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, // No need for locking because we always do this in the main thread. listeners->AppendElement(listener); + MediaStreamConstraints c(aConstraints); // copy + // Developer preference for turning off permission check. if (Preferences::GetBool("media.navigator.permission.disabled", false)) { aPrivileged = true; @@ -1567,7 +1562,7 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, nsresult MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow, - const MediaStreamConstraintsInternal& aConstraints, + const MediaStreamConstraints& aConstraints, nsIGetUserMediaDevicesSuccessCallback* aOnSuccess, nsIDOMGetUserMediaErrorCallback* aOnError, uint64_t aInnerWindowID) diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index 052bd72a69b4..5a796b019718 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -495,14 +495,14 @@ public: void RemoveFromWindowList(uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener); - nsresult GetUserMedia(JSContext* aCx, bool aPrivileged, + nsresult GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow, const dom::MediaStreamConstraints& aRawConstraints, nsIDOMGetUserMediaSuccessCallback* onSuccess, nsIDOMGetUserMediaErrorCallback* onError); nsresult GetUserMediaDevices(nsPIDOMWindow* aWindow, - const dom::MediaStreamConstraintsInternal& aConstraints, + const dom::MediaStreamConstraints& aConstraints, nsIGetUserMediaDevicesSuccessCallback* onSuccess, nsIDOMGetUserMediaErrorCallback* onError, uint64_t aInnerWindowID = 0); diff --git a/dom/media/MediaPermissionGonk.cpp b/dom/media/MediaPermissionGonk.cpp index 2f31a800916e..408cf9c7307c 100644 --- a/dom/media/MediaPermissionGonk.cpp +++ b/dom/media/MediaPermissionGonk.cpp @@ -176,7 +176,7 @@ MediaPermissionRequest::MediaPermissionRequest(nsRefPtr > &aDevices) : mRequest(aRequest) { - dom::MediaStreamConstraintsInternal constraints; + dom::MediaStreamConstraints constraints; mRequest->GetConstraints(constraints); mAudio = !constraints.mAudio.IsBoolean() || constraints.mAudio.GetAsBoolean(); @@ -578,7 +578,7 @@ MediaPermissionManager::HandleRequest(nsRefPtr &req) nsCOMPtr onError = new MediaDeviceErrorCallback(callID); - dom::MediaStreamConstraintsInternal constraints; + dom::MediaStreamConstraints constraints; req->GetConstraints(constraints); nsRefPtr MediaMgr = MediaManager::GetInstance(); diff --git a/dom/media/tests/mochitest/test_getUserMedia_constraints.html b/dom/media/tests/mochitest/test_getUserMedia_constraints.html index ff58d03b3346..efbe1939c731 100644 --- a/dom/media/tests/mochitest/test_getUserMedia_constraints.html +++ b/dom/media/tests/mochitest/test_getUserMedia_constraints.html @@ -20,24 +20,54 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=882145