Bug 1213517 - Consider competing required constraints with OverconstrainedError.
MozReview-Commit-ID: EHIY1hpaEQn
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1388,18 +1388,20 @@ public:
, mSourceSet(aSourceSet)
, mManager(MediaManager::GetInstance())
{}
~GetUserMediaTask() {
}
void
- Fail(const nsAString& aName, const nsAString& aMessage = EmptyString()) {
- RefPtr<MediaMgrError> error = new MediaMgrError(aName, aMessage);
+ Fail(const nsAString& aName,
+ const nsAString& aMessage = EmptyString(),
+ const nsAString& aConstraint = EmptyString()) {
+ RefPtr<MediaMgrError> error = new MediaMgrError(aName, aMessage, aConstraint);
RefPtr<ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>> runnable =
new ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>(mOnSuccess,
mOnFailure,
*error,
mWindowID);
// These should be empty now
MOZ_ASSERT(!mOnSuccess);
MOZ_ASSERT(!mOnFailure);
@@ -1416,40 +1418,65 @@ public:
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
MOZ_ASSERT(mDeviceChosen);
// Allocate a video or audio device and return a MediaStream via
// a GetUserMediaStreamRunnable.
nsresult rv;
+ const char* errorMsg = nullptr;
+ const char* badConstraint = nullptr;
if (mAudioDevice) {
- rv = mAudioDevice->Allocate(GetInvariant(mConstraints.mAudio),
- mPrefs, mOrigin);
+ auto& constraints = GetInvariant(mConstraints.mAudio);
+ rv = mAudioDevice->Allocate(constraints, mPrefs, mOrigin);
if (NS_FAILED(rv)) {
- LOG(("Failed to allocate audiosource %d",rv));
- Fail(NS_LITERAL_STRING("NotReadableError"),
- NS_LITERAL_STRING("Failed to allocate audiosource"));
- return NS_OK;
+ errorMsg = "Failed to allocate audiosource";
+ if (rv == NS_ERROR_NOT_AVAILABLE) {
+ nsTArray<RefPtr<AudioDevice>> audios;
+ audios.AppendElement(mAudioDevice);
+ badConstraint = MediaConstraintsHelper::SelectSettings(constraints,
+ audios);
+ }
}
}
- if (mVideoDevice) {
- rv = mVideoDevice->Allocate(GetInvariant(mConstraints.mVideo),
- mPrefs, mOrigin);
+ if (!errorMsg && mVideoDevice) {
+ auto& constraints = GetInvariant(mConstraints.mVideo);
+ rv = mVideoDevice->Allocate(constraints, mPrefs, mOrigin);
if (NS_FAILED(rv)) {
- LOG(("Failed to allocate videosource %d\n",rv));
+ errorMsg = "Failed to allocate videosource";
+ if (rv == NS_ERROR_NOT_AVAILABLE) {
+ nsTArray<RefPtr<VideoDevice>> videos;
+ videos.AppendElement(mVideoDevice);
+ badConstraint = MediaConstraintsHelper::SelectSettings(constraints,
+ videos);
+ }
if (mAudioDevice) {
mAudioDevice->Deallocate();
}
- Fail(NS_LITERAL_STRING("NotReadableError"),
- NS_LITERAL_STRING("Failed to allocate videosource"));
- return NS_OK;
}
}
+ if (errorMsg) {
+ LOG(("%s %d", errorMsg, rv));
+ switch (rv) {
+ case NS_ERROR_NOT_AVAILABLE: {
+ MOZ_ASSERT(badConstraint);
+ Fail(NS_LITERAL_STRING("OverconstrainedError"),
+ NS_LITERAL_STRING(""),
+ NS_ConvertUTF8toUTF16(badConstraint));
+ break;
+ }
+ default:
+ Fail(NS_LITERAL_STRING("NotReadableError"),
+ NS_ConvertUTF8toUTF16(errorMsg));
+ break;
+ }
+ return NS_OK;
+ }
PeerIdentity* peerIdentity = nullptr;
if (!mConstraints.mPeerIdentity.IsEmpty()) {
peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
}
NS_DispatchToMainThread(do_AddRef(
new GetUserMediaStreamRunnable(mOnSuccess, mOnFailure, mWindowID,
mListener, mOrigin, mConstraints,
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -117,21 +117,21 @@ MediaEngineRemoteVideoSource::Allocate(
for (auto& registered : mRegisteredHandles) {
allConstraints.AppendElement(®istered->mConstraints);
}
RefPtr<AllocationHandle> handle = new AllocationHandle(aConstraints);
allConstraints.AppendElement(&handle->mConstraints);
NormalizedConstraints netConstraints(allConstraints);
if (netConstraints.mOverconstrained) {
- return NS_ERROR_FAILURE;
+ return NS_ERROR_NOT_AVAILABLE;
}
if (!ChooseCapability(netConstraints, aPrefs, aDeviceId)) {
- return NS_ERROR_FAILURE;
+ return NS_ERROR_NOT_AVAILABLE;
}
if (mState == kReleased) {
if (mozilla::camera::GetChildAndCall(
&mozilla::camera::CamerasChild::AllocateCaptureDevice,
mCapEngine, GetUUID().get(), kMaxUniqueIdLength, mCaptureIndex, aOrigin)) {
return NS_ERROR_FAILURE;
}