// Deprecated. WebMediaConstraints create(const Dictionary& constraintsDictionary, MediaErrorState& errorState) { WebVector<WebMediaConstraint> optional; WebVector<WebMediaConstraint> mandatory; if (!parse(constraintsDictionary, optional, mandatory)) { errorState.throwTypeError("Malformed constraints object."); return WebMediaConstraints(); } return createFromNamedConstraints(mandatory, optional, errorState); }
ScriptPromise MediaDevices::getUserMedia(ScriptState* scriptState, const MediaStreamConstraints& options, ExceptionState& exceptionState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); NavigatorUserMediaSuccessCallback* successCallback = new PromiseSuccessCallback(resolver); NavigatorUserMediaErrorCallback* errorCallback = new PromiseErrorCallback(resolver); Document* document = toDocument(scriptState->getExecutionContext()); UserMediaController* userMedia = UserMediaController::from(document->frame()); if (!userMedia) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NotSupportedError, "No media device controller available; is this a " "detached window?")); MediaErrorState errorState; UserMediaRequest* request = UserMediaRequest::create( document, userMedia, options, successCallback, errorCallback, errorState); if (!request) { DCHECK(errorState.hadException()); if (errorState.canGenerateException()) { errorState.raiseException(exceptionState); return exceptionState.reject(scriptState); } ScriptPromise rejectedPromise = resolver->promise(); resolver->reject(errorState.createError()); return rejectedPromise; } String errorMessage; if (!request->isSecureContextUse(errorMessage)) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NotSupportedError, errorMessage)); } request->start(); return resolver->promise(); }
WebMediaConstraints create(const MediaTrackConstraintSet& constraintsIn, MediaErrorState& errorState) { WebMediaConstraints constraints; WebMediaTrackConstraintSet constraintBuffer; WebVector<WebMediaTrackConstraintSet> advancedBuffer; copyConstraints(constraintsIn, constraintBuffer); // TODO(hta): Add initialization of advanced constraints once present. // https://crbug.com/253412 if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) { if (!constraintBuffer.isEmpty()) { errorState.throwTypeError("Malformed constraint: Cannot use both optional/mandatory and specific constraints."); return WebMediaConstraints(); } WebVector<WebMediaConstraint> optional; WebVector<WebMediaConstraint> mandatory; if (!parse(constraintsIn, optional, mandatory)) { errorState.throwTypeError("Malformed constraints object."); return WebMediaConstraints(); } return createFromNamedConstraints(mandatory, optional, errorState); } constraints.initialize(constraintBuffer, advancedBuffer); return constraints; }
static WebMediaConstraints createFromNamedConstraints(WebVector<WebMediaConstraint>& mandatory, const WebVector<WebMediaConstraint>& optional, MediaErrorState& errorState) { WebMediaTrackConstraintSet basic; WebMediaTrackConstraintSet advanced; WebMediaConstraints constraints; if (RuntimeEnabledFeatures::mediaConstraintsEnabled()) { parseOldStyleNames(mandatory, basic, errorState); if (errorState.hadException()) return constraints; // We ignore errors in optional constraints. MediaErrorState ignoredErrorState; parseOldStyleNames(optional, advanced, ignoredErrorState); } WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1); // Use the 4-argument initializer until Chrome has been converted. constraints.initialize(optional, mandatory, basic, advancedVector); return constraints; }
static void parseOldStyleNames(const WebVector<WebMediaConstraint>& oldNames, WebMediaTrackConstraintSet& result, MediaErrorState& errorState) { for (const WebMediaConstraint& constraint : oldNames) { if (constraint.m_name.equals(kMinAspectRatio)) { result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMaxAspectRatio)) { result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMaxWidth)) { result.width.setMax(atoi(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMinWidth)) { result.width.setMin(atoi(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMaxHeight)) { result.height.setMax(atoi(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMinHeight)) { result.height.setMin(atoi(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMinFrameRate)) { result.frameRate.setMin(atof(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kMaxFrameRate)) { result.frameRate.setMax(atof(constraint.m_value.utf8().c_str())); } else if (constraint.m_name.equals(kEchoCancellation)) { result.echoCancellation.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kMediaStreamSource)) { // TODO(hta): This has only a few legal values. Should be // represented as an enum, and cause type errors. // https://crbug.com/576582 result.mediaStreamSource.setExact(constraint.m_value); } else if (constraint.m_name.equals(kMediaStreamSourceId)) { result.deviceId.setExact(constraint.m_value); } else if (constraint.m_name.equals(kMediaStreamRenderToAssociatedSink)) { // TODO(hta): This is a boolean represented as string. // Should give TypeError when it's not parseable. // https://crbug.com/576582 result.renderToAssociatedSink.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kMediaStreamAudioHotword)) { result.hotwordEnabled.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogEchoCancellation)) { result.googEchoCancellation.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogExperimentalEchoCancellation)) { result.googExperimentalEchoCancellation.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogAutoGainControl)) { result.googAutoGainControl.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogExperimentalAutoGainControl)) { result.googExperimentalAutoGainControl.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogNoiseSuppression)) { result.googNoiseSuppression.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogExperimentalNoiseSuppression)) { result.googExperimentalNoiseSuppression.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogBeamforming)) { result.googBeamforming.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogArrayGeometry)) { result.googArrayGeometry.setExact(constraint.m_value); } else if (constraint.m_name.equals(kGoogHighpassFilter)) { result.googHighpassFilter.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogTypingNoiseDetection)) { result.googTypingNoiseDetection.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kGoogAudioMirroring)) { result.googAudioMirroring.setExact(toBoolean(constraint.m_value)); } else if (constraint.m_name.equals(kTestConstraint1) || constraint.m_name.equals(kTestConstraint2)) { // These constraints are only for testing parsing. Ignore them. } else { // TODO(hta): UMA stats for unknown constraints passed. // https://crbug.com/576613 WTF_LOG(Media, "Unknown constraint name detected"); errorState.throwConstraintError("Unknown name of constraint detected", constraint.m_name); } } }