| Index: third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
|
| diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
|
| index 51287a578a7adcdecce96b681a2ef061238f3f00..503dd846091b7bf4dca198fdc0670d4eb747c22f 100644
|
| --- a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
|
| +++ b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
|
| @@ -31,6 +31,8 @@
|
|
|
| #include "modules/mediastream/UserMediaRequest.h"
|
|
|
| +#include <type_traits>
|
| +
|
| #include "bindings/core/v8/Dictionary.h"
|
| #include "bindings/core/v8/ExceptionMessages.h"
|
| #include "bindings/core/v8/ExceptionState.h"
|
| @@ -49,10 +51,259 @@
|
|
|
| namespace blink {
|
|
|
| -static WebMediaConstraints ParseOptions(
|
| - ExecutionContext* context,
|
| - const BooleanOrMediaTrackConstraints& options,
|
| - MediaErrorState& error_state) {
|
| +namespace {
|
| +
|
| +template <typename NumericConstraint>
|
| +bool SetUsesNumericConstraint(
|
| + const WebMediaTrackConstraintSet& set,
|
| + NumericConstraint WebMediaTrackConstraintSet::*field) {
|
| + return (set.*field).HasExact() || (set.*field).HasIdeal() ||
|
| + (set.*field).HasMin() || (set.*field).HasMax();
|
| +}
|
| +
|
| +template <typename DiscreteConstraint>
|
| +bool SetUsesDiscreteConstraint(
|
| + const WebMediaTrackConstraintSet& set,
|
| + DiscreteConstraint WebMediaTrackConstraintSet::*field) {
|
| + return (set.*field).HasExact() || (set.*field).HasIdeal();
|
| +}
|
| +
|
| +template <typename NumericConstraint>
|
| +bool RequestUsesNumericConstraint(
|
| + const WebMediaConstraints& constraints,
|
| + NumericConstraint WebMediaTrackConstraintSet::*field) {
|
| + if (SetUsesNumericConstraint(constraints.Basic(), field))
|
| + return true;
|
| + for (const auto& advanced_set : constraints.Advanced()) {
|
| + if (SetUsesNumericConstraint(advanced_set, field))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +template <typename DiscreteConstraint>
|
| +bool RequestUsesDiscreteConstraint(
|
| + const WebMediaConstraints& constraints,
|
| + DiscreteConstraint WebMediaTrackConstraintSet::*field) {
|
| + static_assert(
|
| + std::is_same<decltype(field),
|
| + StringConstraint WebMediaTrackConstraintSet::*>::value ||
|
| + std::is_same<decltype(field),
|
| + BooleanConstraint WebMediaTrackConstraintSet::*>::value,
|
| + "Must use StringConstraint or BooleanConstraint");
|
| + if (SetUsesDiscreteConstraint(constraints.Basic(), field))
|
| + return true;
|
| + for (const auto& advanced_set : constraints.Advanced()) {
|
| + if (SetUsesDiscreteConstraint(advanced_set, field))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +class FeatureCounter {
|
| + WTF_MAKE_NONCOPYABLE(FeatureCounter);
|
| +
|
| + public:
|
| + FeatureCounter(ExecutionContext* context)
|
| + : context_(context), is_unconstrained_(true) {}
|
| + void Count(UseCounter::Feature feature) {
|
| + UseCounter::Count(context_, feature);
|
| + is_unconstrained_ = false;
|
| + }
|
| + bool IsUnconstrained() { return is_unconstrained_; }
|
| +
|
| + private:
|
| + Persistent<ExecutionContext> context_;
|
| + bool is_unconstrained_;
|
| +};
|
| +
|
| +void CountAudioConstraintUses(ExecutionContext* context,
|
| + const WebMediaConstraints& constraints) {
|
| + FeatureCounter counter(context);
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::sample_rate)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsSampleRate);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::sample_size)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsSampleSize);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::echo_cancellation)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsEchoCancellation);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::latency)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsLatency);
|
| + }
|
| + if (RequestUsesNumericConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::channel_count)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsChannelCount);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::device_id)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsDeviceIdAudio);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::disable_local_echo)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsDisableLocalEcho);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::group_id)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGroupIdAudio);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::media_stream_source)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsMediaStreamSourceAudio);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::render_to_associated_sink)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsRenderToAssociatedSink);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::hotword_enabled)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsHotwordEnabled);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_echo_cancellation)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogEchoCancellation);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_experimental_echo_cancellation)) {
|
| + counter.Count(
|
| + UseCounter::kMediaStreamConstraintsGoogExperimentalEchoCancellation);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_auto_gain_control)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogAutoGainControl);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_experimental_auto_gain_control)) {
|
| + counter.Count(
|
| + UseCounter::kMediaStreamConstraintsGoogExperimentalAutoGainControl);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_noise_suppression)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogNoiseSuppression);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_highpass_filter)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogHighpassFilter);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_typing_noise_detection)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogTypingNoiseDetection);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_experimental_noise_suppression)) {
|
| + counter.Count(
|
| + UseCounter::kMediaStreamConstraintsGoogExperimentalNoiseSuppression);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_beamforming)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogBeamforming);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_array_geometry)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogArrayGeometry);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_audio_mirroring)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogAudioMirroring);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_da_echo_cancellation)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogDAEchoCancellation);
|
| + }
|
| +
|
| + UseCounter::Count(context, UseCounter::kMediaStreamConstraintsAudio);
|
| + if (counter.IsUnconstrained()) {
|
| + UseCounter::Count(context,
|
| + UseCounter::kMediaStreamConstraintsAudioUnconstrained);
|
| + }
|
| +}
|
| +
|
| +void CountVideoConstraintUses(ExecutionContext* context,
|
| + const WebMediaConstraints& constraints) {
|
| + FeatureCounter counter(context);
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::width)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsWidth);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::height)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsHeight);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::aspect_ratio)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsAspectRatio);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::frame_rate)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsFrameRate);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::facing_mode)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsFacingMode);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::device_id)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsDeviceIdVideo);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::group_id)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGroupIdVideo);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::video_kind)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsVideoKind);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::depth_near)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsDepthNear);
|
| + }
|
| + if (RequestUsesNumericConstraint(constraints,
|
| + &WebMediaTrackConstraintSet::depth_far)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsDepthFar);
|
| + }
|
| + if (RequestUsesNumericConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::focal_length_x)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsFocalLengthX);
|
| + }
|
| + if (RequestUsesNumericConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::focal_length_y)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsFocalLengthY);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::media_stream_source)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsMediaStreamSourceVideo);
|
| + }
|
| + if (RequestUsesDiscreteConstraint(
|
| + constraints, &WebMediaTrackConstraintSet::goog_noise_reduction)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogNoiseReduction);
|
| + }
|
| + if (RequestUsesNumericConstraint(
|
| + constraints,
|
| + &WebMediaTrackConstraintSet::goog_power_line_frequency)) {
|
| + counter.Count(UseCounter::kMediaStreamConstraintsGoogPowerLineFrequency);
|
| + }
|
| +
|
| + UseCounter::Count(context, UseCounter::kMediaStreamConstraintsVideo);
|
| + if (counter.IsUnconstrained()) {
|
| + UseCounter::Count(context,
|
| + UseCounter::kMediaStreamConstraintsVideoUnconstrained);
|
| + }
|
| +}
|
| +
|
| +WebMediaConstraints ParseOptions(ExecutionContext* context,
|
| + const BooleanOrMediaTrackConstraints& options,
|
| + MediaErrorState& error_state) {
|
| WebMediaConstraints constraints;
|
|
|
| Dictionary constraints_dictionary;
|
| @@ -71,6 +322,8 @@ static WebMediaConstraints ParseOptions(
|
| return constraints;
|
| }
|
|
|
| +} // namespace
|
| +
|
| UserMediaRequest* UserMediaRequest::Create(
|
| ExecutionContext* context,
|
| UserMediaController* controller,
|
| @@ -94,6 +347,11 @@ UserMediaRequest* UserMediaRequest::Create(
|
| return nullptr;
|
| }
|
|
|
| + if (!audio.IsNull())
|
| + CountAudioConstraintUses(context, audio);
|
| + if (!video.IsNull())
|
| + CountVideoConstraintUses(context, video);
|
| +
|
| return new UserMediaRequest(context, controller, audio, video,
|
| success_callback, error_callback);
|
| }
|
|
|