// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h"

#include <algorithm>
#include <cmath>
#include <memory>
#include <string>
#include <utility>

#include "base/callback_helpers.h"
#include "base/containers/contains.h"
#include "build/build_config.h"
#include "media/base/audio_parameters.h"
#include "media/webrtc/webrtc_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"

namespace blink {

using blink::AudioCaptureSettings;
using blink::AudioProcessingProperties;
using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
using ProcessingType = AudioCaptureSettings::ProcessingType;

namespace {

using BoolSetFunction = void (blink::BooleanConstraint::*)(bool);
using StringSetFunction =
    void (blink::StringConstraint::*)(const blink::WebString&);
using MockFactoryAccessor =
    MediaTrackConstraintSetPlatform& (blink::MockConstraintFactory::*)();

const BoolSetFunction kBoolSetFunctions[] = {
    &blink::BooleanConstraint::SetExact,
    &blink::BooleanConstraint::SetIdeal,
};

const MockFactoryAccessor kFactoryAccessors[] = {
    &blink::MockConstraintFactory::basic,
    &blink::MockConstraintFactory::AddAdvanced};

const bool kBoolValues[] = {true, false};

const int kMinChannels = 1;

using AudioSettingsBoolMembers =
    std::vector<bool (AudioCaptureSettings::*)() const>;
using AudioPropertiesBoolMembers =
    std::vector<bool AudioProcessingProperties::*>;

const AudioPropertiesBoolMembers kAudioProcessingProperties = {
    &AudioProcessingProperties::goog_audio_mirroring,
    &AudioProcessingProperties::goog_auto_gain_control,
    &AudioProcessingProperties::goog_experimental_echo_cancellation,
    &AudioProcessingProperties::goog_noise_suppression,
    &AudioProcessingProperties::goog_experimental_noise_suppression,
    &AudioProcessingProperties::goog_highpass_filter,
    &AudioProcessingProperties::goog_experimental_auto_gain_control};

template <typename T>
static bool Contains(const std::vector<T>& vector, T value) {
  return base::Contains(vector, value);
}

}  // namespace

class MediaStreamConstraintsUtilAudioTestBase {
 protected:
  void MakeSystemEchoCancellerDeviceExperimental() {
    media::AudioParameters experimental_system_echo_canceller_parameters(
        media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
        media::CHANNEL_LAYOUT_STEREO,
        media::AudioParameters::kAudioCDSampleRate, 1000);
    experimental_system_echo_canceller_parameters.set_effects(
        media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
    capabilities_[1] = {"experimental_system_echo_canceller_device",
                        "fake_group3",
                        experimental_system_echo_canceller_parameters};
  }

  void SetMediaStreamSource(const std::string& source) {}

  void ResetFactory() {
    constraint_factory_.Reset();
    constraint_factory_.basic().media_stream_source.SetExact(
        String::FromUTF8(GetMediaStreamSource()));
  }

  // If not overridden, this function will return device capture by default.
  virtual std::string GetMediaStreamSource() { return std::string(); }
  bool IsDeviceCapture() { return GetMediaStreamSource().empty(); }

  blink::mojom::MediaStreamType GetMediaStreamType() {
    std::string media_source = GetMediaStreamSource();
    if (media_source.empty())
      return blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE;
    else if (media_source == blink::kMediaStreamSourceTab)
      return blink::mojom::MediaStreamType::GUM_TAB_AUDIO_CAPTURE;
    return blink::mojom::MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE;
  }

  std::unique_ptr<ProcessedLocalAudioSource> GetProcessedLocalAudioSource(
      const AudioProcessingProperties& properties,
      bool disable_local_echo,
      bool render_to_associated_sink,
      int effects) {
    blink::MediaStreamDevice device;
    device.id = "processed_source";
    device.type = GetMediaStreamType();
    if (render_to_associated_sink)
      device.matched_output_device_id = std::string("some_device_id");
    device.input.set_effects(effects);

    return std::make_unique<ProcessedLocalAudioSource>(
        nullptr /*web_frame*/, device, disable_local_echo, properties,
        base::NullCallback(),
        blink::scheduler::GetSingleThreadTaskRunnerForTesting());
  }

  std::unique_ptr<ProcessedLocalAudioSource> GetProcessedLocalAudioSource(
      const AudioProcessingProperties& properties,
      bool disable_local_echo,
      bool render_to_associated_sink) {
    return GetProcessedLocalAudioSource(
        properties, disable_local_echo, render_to_associated_sink,
        media::AudioParameters::PlatformEffectsMask::NO_EFFECTS);
  }

  std::unique_ptr<blink::LocalMediaStreamAudioSource>
  GetLocalMediaStreamAudioSource(
      bool enable_system_echo_canceller,
      bool disable_local_echo,
      bool render_to_associated_sink,
      bool enable_experimental_echo_canceller = false,
      const int* requested_buffer_size = nullptr) {
    blink::MediaStreamDevice device;
    device.type = GetMediaStreamType();

    int effects = 0;
    if (enable_system_echo_canceller)
      effects |= media::AudioParameters::ECHO_CANCELLER;
    if (enable_experimental_echo_canceller)
      effects |= media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER;
    device.input.set_effects(effects);

    if (render_to_associated_sink)
      device.matched_output_device_id = std::string("some_device_id");

    return std::make_unique<blink::LocalMediaStreamAudioSource>(
        /*blink::WebLocalFrame=*/nullptr, device, requested_buffer_size,
        disable_local_echo,
        blink::WebPlatformMediaStreamSource::ConstraintsRepeatingCallback(),
        blink::scheduler::GetSingleThreadTaskRunnerForTesting());
  }

  AudioCaptureSettings SelectSettings(
      bool is_reconfigurable = false,
      base::Optional<AudioDeviceCaptureCapabilities> capabilities =
          base::nullopt) {
    MediaConstraints constraints = constraint_factory_.CreateMediaConstraints();
    if (capabilities) {
      return SelectSettingsAudioCapture(*capabilities, constraints, false,
                                        is_reconfigurable);
    } else {
      return SelectSettingsAudioCapture(capabilities_, constraints, false,
                                        is_reconfigurable);
    }
  }

  // When googExperimentalEchoCancellation is not explicitly set, its default
  // value is always false on Android. On other platforms it behaves like other
  // audio-processing properties.
  void CheckGoogExperimentalEchoCancellationDefault(
      const AudioProcessingProperties& properties,
      bool value) {
#if defined(OS_ANDROID)
    EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
#else
    EXPECT_EQ(value, properties.goog_experimental_echo_cancellation);
#endif
  }

  void CheckBoolDefaultsDeviceCapture(
      const AudioSettingsBoolMembers& exclude_main_settings,
      const AudioPropertiesBoolMembers& exclude_audio_properties,
      const AudioCaptureSettings& result) {
    if (!Contains(exclude_main_settings,
                  &AudioCaptureSettings::disable_local_echo)) {
      EXPECT_TRUE(result.disable_local_echo());
    }
    if (!Contains(exclude_main_settings,
                  &AudioCaptureSettings::render_to_associated_sink)) {
      EXPECT_FALSE(result.render_to_associated_sink());
    }

    const auto& properties = result.audio_processing_properties();
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_audio_mirroring)) {
      EXPECT_FALSE(properties.goog_audio_mirroring);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_auto_gain_control)) {
      EXPECT_EQ(properties.goog_auto_gain_control,
                properties.goog_experimental_auto_gain_control);
      if (!Contains(exclude_audio_properties,
                    &AudioProcessingProperties::
                        goog_experimental_auto_gain_control)) {
        EXPECT_TRUE(properties.goog_auto_gain_control);
      }
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
      EXPECT_EQ(properties.goog_auto_gain_control,
                properties.goog_experimental_auto_gain_control);
      if (!Contains(exclude_audio_properties,
                    &AudioProcessingProperties::goog_auto_gain_control)) {
        EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
      }
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_echo_cancellation)) {
      CheckGoogExperimentalEchoCancellationDefault(properties, true);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_noise_suppression)) {
      EXPECT_TRUE(properties.goog_noise_suppression);
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_noise_suppression)) {
      EXPECT_TRUE(properties.goog_experimental_noise_suppression);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_highpass_filter)) {
      EXPECT_TRUE(properties.goog_highpass_filter);
    }
  }

  void CheckBoolDefaultsContentCapture(
      const AudioSettingsBoolMembers& exclude_main_settings,
      const AudioPropertiesBoolMembers& exclude_audio_properties,
      const AudioCaptureSettings& result) {
    if (!Contains(exclude_main_settings,
                  &AudioCaptureSettings::disable_local_echo)) {
      EXPECT_EQ(GetMediaStreamSource() != blink::kMediaStreamSourceDesktop,
                result.disable_local_echo());
    }
    if (!Contains(exclude_main_settings,
                  &AudioCaptureSettings::render_to_associated_sink)) {
      EXPECT_FALSE(result.render_to_associated_sink());
    }

    const auto& properties = result.audio_processing_properties();
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_audio_mirroring)) {
      EXPECT_FALSE(properties.goog_audio_mirroring);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_auto_gain_control)) {
      EXPECT_EQ(properties.goog_auto_gain_control,
                properties.goog_experimental_auto_gain_control);
      if (!Contains(exclude_audio_properties,
                    &AudioProcessingProperties::
                        goog_experimental_auto_gain_control)) {
        EXPECT_FALSE(properties.goog_auto_gain_control);
      }
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
      EXPECT_EQ(properties.goog_auto_gain_control,
                properties.goog_experimental_auto_gain_control);
      if (!Contains(exclude_audio_properties,
                    &AudioProcessingProperties::goog_auto_gain_control)) {
        EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
      }
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_echo_cancellation)) {
      EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_noise_suppression)) {
      EXPECT_FALSE(properties.goog_noise_suppression);
    }
    if (!Contains(
            exclude_audio_properties,
            &AudioProcessingProperties::goog_experimental_noise_suppression)) {
      EXPECT_FALSE(properties.goog_experimental_noise_suppression);
    }
    if (!Contains(exclude_audio_properties,
                  &AudioProcessingProperties::goog_highpass_filter)) {
      EXPECT_FALSE(properties.goog_highpass_filter);
    }
  }

  void CheckBoolDefaults(
      const AudioSettingsBoolMembers& exclude_main_settings,
      const AudioPropertiesBoolMembers& exclude_audio_properties,
      const AudioCaptureSettings& result) {
    if (IsDeviceCapture()) {
      CheckBoolDefaultsDeviceCapture(exclude_main_settings,
                                     exclude_audio_properties, result);
    } else {
      CheckBoolDefaultsContentCapture(exclude_main_settings,
                                      exclude_audio_properties, result);
    }
  }

  void CheckEchoCancellationTypeDefault(const AudioCaptureSettings& result) {
    const auto& properties = result.audio_processing_properties();
    if (IsDeviceCapture()) {
      EXPECT_EQ(properties.echo_cancellation_type,
                EchoCancellationType::kEchoCancellationAec3);
    } else {
      EXPECT_EQ(properties.echo_cancellation_type,
                EchoCancellationType::kEchoCancellationDisabled);
    }
  }

  void CheckProcessingType(const AudioCaptureSettings& result) {
    ProcessingType expected_type = ProcessingType::kUnprocessed;
    const auto& properties = result.audio_processing_properties();
    bool properties_value = false;
    // Skip audio mirroring and start directly from auto gain control.
    for (size_t i = 1; i < kAudioProcessingProperties.size(); ++i)
      properties_value |= properties.*kAudioProcessingProperties[i];

    // If goog_audio_mirroring is true but all the other properties are false,
    // we should be expecting kProcessed, however if any of the properties was
    // true, we should expected kApmProcessed.
    if (properties.goog_audio_mirroring && !properties_value)
      expected_type = ProcessingType::kNoApmProcessed;
    else if (properties_value)
      expected_type = ProcessingType::kApmProcessed;

    // Finally, if the chosen echo cancellation type is either AEC3 or AEC2, the
    // only possible processing type to expect is kWebRtcProcessed.
    if (properties.echo_cancellation_type ==
        EchoCancellationType::kEchoCancellationAec3) {
      expected_type = ProcessingType::kApmProcessed;
    }
    EXPECT_EQ(result.processing_type(), expected_type);
  }

  void CheckDevice(const AudioDeviceCaptureCapability& expected_device,
                   const AudioCaptureSettings& result) {
    EXPECT_EQ(expected_device.DeviceID().Utf8(), result.device_id());
  }

  void CheckDeviceDefaults(const AudioCaptureSettings& result) {
    if (IsDeviceCapture())
      CheckDevice(*default_device_, result);
    else
      EXPECT_TRUE(result.device_id().empty());
  }

  void CheckAllDefaults(
      const AudioSettingsBoolMembers& exclude_main_settings,
      const AudioPropertiesBoolMembers& exclude_audio_properties,
      const AudioCaptureSettings& result) {
    CheckProcessingType(result);
    CheckBoolDefaults(exclude_main_settings, exclude_audio_properties, result);
    CheckEchoCancellationTypeDefault(result);
    CheckDeviceDefaults(result);
  }

  void CheckAudioProcessingPropertiesForIdealEchoCancellationType(
      const AudioCaptureSettings& result) {
    const AudioProcessingProperties& properties =
        result.audio_processing_properties();

    EXPECT_EQ(EchoCancellationType::kEchoCancellationSystem,
              properties.echo_cancellation_type);
    EXPECT_TRUE(properties.goog_auto_gain_control);
    CheckGoogExperimentalEchoCancellationDefault(properties, true);
    EXPECT_TRUE(properties.goog_noise_suppression);
    EXPECT_TRUE(properties.goog_experimental_noise_suppression);
    EXPECT_TRUE(properties.goog_highpass_filter);
    EXPECT_TRUE(properties.goog_experimental_auto_gain_control);

    // The following are not audio processing.
    EXPECT_FALSE(properties.goog_audio_mirroring);
    EXPECT_EQ(GetMediaStreamSource() != blink::kMediaStreamSourceDesktop,
              result.disable_local_echo());
    EXPECT_FALSE(result.render_to_associated_sink());
    CheckDevice(*system_echo_canceller_device_, result);
  }

  EchoCancellationType GetEchoCancellationTypeFromConstraintString(
      const blink::WebString& constraint_string) {
    if (constraint_string == kEchoCancellationTypeValues[0])
      return EchoCancellationType::kEchoCancellationAec3;
    if (constraint_string == kEchoCancellationTypeValues[1])
      return EchoCancellationType::kEchoCancellationAec3;
    if (constraint_string == kEchoCancellationTypeValues[2])
      return EchoCancellationType::kEchoCancellationSystem;

    ADD_FAILURE() << "Invalid echo cancellation type constraint: "
                  << constraint_string.Ascii();
    return EchoCancellationType::kEchoCancellationDisabled;
  }

  void CheckLatencyConstraint(const AudioDeviceCaptureCapability* device,
                              double min_latency,
                              double max_latency) {
    constraint_factory_.Reset();
    constraint_factory_.basic().device_id.SetExact(device->DeviceID());
    constraint_factory_.basic().echo_cancellation.SetExact(false);
    constraint_factory_.basic().latency.SetExact(0.0);
    auto result = SelectSettings();
    EXPECT_FALSE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().device_id.SetExact(device->DeviceID());
    constraint_factory_.basic().echo_cancellation.SetExact(false);
    constraint_factory_.basic().latency.SetMin(max_latency + 0.001);
    result = SelectSettings();
    EXPECT_FALSE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().device_id.SetExact(device->DeviceID());
    constraint_factory_.basic().echo_cancellation.SetExact(false);
    constraint_factory_.basic().latency.SetMax(min_latency - 0.001);
    result = SelectSettings();
    EXPECT_FALSE(result.HasValue());

    CheckLocalMediaStreamAudioSourceLatency(
        device, 0.001, min_latency * device->Parameters().sample_rate());
    CheckLocalMediaStreamAudioSourceLatency(
        device, 1.0, max_latency * device->Parameters().sample_rate());
  }

  void CheckLocalMediaStreamAudioSourceLatency(
      const AudioDeviceCaptureCapability* device,
      double requested_latency,
      int expected_buffer_size) {
    constraint_factory_.Reset();
    constraint_factory_.basic().device_id.SetExact(device->DeviceID());
    constraint_factory_.basic().echo_cancellation.SetExact(false);
    constraint_factory_.basic().latency.SetIdeal(requested_latency);
    auto result = SelectSettings();
    EXPECT_TRUE(result.HasValue());

    std::unique_ptr<blink::LocalMediaStreamAudioSource> local_source =
        GetLocalMediaStreamAudioSource(
            false /* enable_system_echo_canceller */,
            false /* disable_local_echo */,
            false /* render_to_associated_sink */,
            false /* enable_experimental_echo_canceller */,
            base::OptionalOrNullptr(result.requested_buffer_size()));
    EXPECT_EQ(local_source->GetAudioParameters().frames_per_buffer(),
              expected_buffer_size);
  }

  blink::MockConstraintFactory constraint_factory_;
  AudioDeviceCaptureCapabilities capabilities_;
  const AudioDeviceCaptureCapability* default_device_ = nullptr;
  const AudioDeviceCaptureCapability* system_echo_canceller_device_ = nullptr;
  const AudioDeviceCaptureCapability* four_channels_device_ = nullptr;
  const AudioDeviceCaptureCapability* variable_latency_device_ = nullptr;
  std::unique_ptr<ProcessedLocalAudioSource> system_echo_canceller_source_ =
      nullptr;
  const std::vector<media::Point> kMicPositions = {{8, 8, 8}, {4, 4, 4}};

  // TODO(grunell): Store these as separate constants and compare against those
  // in tests, instead of indexing the vector.
  const std::vector<blink::WebString> kEchoCancellationTypeValues = {
      blink::WebString::FromASCII("browser"),
      blink::WebString::FromASCII("aec3"),
      blink::WebString::FromASCII("system")};

 private:
  ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
};

class MediaStreamConstraintsUtilAudioTest
    : public MediaStreamConstraintsUtilAudioTestBase,
      public testing::TestWithParam<std::string> {
 public:
  void SetUp() override {
    ResetFactory();
    if (IsDeviceCapture()) {
      capabilities_.emplace_back(
          "default_device", "fake_group1",
          media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                 media::CHANNEL_LAYOUT_STEREO,
                                 media::AudioParameters::kAudioCDSampleRate,
                                 1000));

      media::AudioParameters system_echo_canceller_parameters(
          media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
          media::CHANNEL_LAYOUT_STEREO,
          media::AudioParameters::kAudioCDSampleRate, 1000);
      system_echo_canceller_parameters.set_effects(
          media::AudioParameters::ECHO_CANCELLER);
      capabilities_.emplace_back("system_echo_canceller_device", "fake_group2",
                                 system_echo_canceller_parameters);

      capabilities_.emplace_back(
          "4_channels_device", "fake_group3",
          media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                 media::CHANNEL_LAYOUT_4_0,
                                 media::AudioParameters::kAudioCDSampleRate,
                                 1000));

      capabilities_.emplace_back(
          "8khz_sample_rate_device", "fake_group4",
          media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                 media::CHANNEL_LAYOUT_STEREO,
                                 blink::AudioProcessing::kSampleRate8kHz,
                                 1000));

      capabilities_.emplace_back(
          "variable_latency_device", "fake_group5",
          media::AudioParameters(
              media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
              media::CHANNEL_LAYOUT_STEREO,
              media::AudioParameters::kAudioCDSampleRate, 512,
              media::AudioParameters::HardwareCapabilities(128, 4096)));

      default_device_ = &capabilities_[0];
      system_echo_canceller_device_ = &capabilities_[1];
      four_channels_device_ = &capabilities_[2];
      variable_latency_device_ = &capabilities_[4];
    } else {
      // For content capture, use a single capability that admits all possible
      // settings.
      capabilities_.emplace_back();
    }
  }

  std::string GetMediaStreamSource() override { return GetParam(); }
};

// The Unconstrained test checks the default selection criteria.
TEST_P(MediaStreamConstraintsUtilAudioTest, Unconstrained) {
  auto result = SelectSettings();

  // All settings should have default values.
  EXPECT_TRUE(result.HasValue());
  CheckAllDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
                   result);
}

// This test checks all possible ways to set boolean constraints (except
// echo cancellation constraints, which are not mapped 1:1 to output audio
// processing properties).
TEST_P(MediaStreamConstraintsUtilAudioTest, SingleBoolConstraint) {
  AudioSettingsBoolMembers kMainSettings = {
      &AudioCaptureSettings::disable_local_echo,
      &AudioCaptureSettings::render_to_associated_sink};

  const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
      kMainBoolConstraints = {
          &MediaTrackConstraintSetPlatform::disable_local_echo,
          &MediaTrackConstraintSetPlatform::render_to_associated_sink};

  ASSERT_EQ(kMainSettings.size(), kMainBoolConstraints.size());
  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (size_t i = 0; i < kMainSettings.size(); ++i) {
        for (bool value : kBoolValues) {
          ResetFactory();
          (((constraint_factory_.*accessor)().*kMainBoolConstraints[i]).*
           set_function)(value);
          auto result = SelectSettings();
          EXPECT_TRUE(result.HasValue());
          EXPECT_EQ(value, (result.*kMainSettings[i])());
          CheckAllDefaults({kMainSettings[i]}, AudioPropertiesBoolMembers(),
                           result);
        }
      }
    }
  }

  const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
      kAudioProcessingConstraints = {
          &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
          &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
          &MediaTrackConstraintSetPlatform::goog_experimental_echo_cancellation,
          &MediaTrackConstraintSetPlatform::goog_noise_suppression,
          &MediaTrackConstraintSetPlatform::goog_experimental_noise_suppression,
          &MediaTrackConstraintSetPlatform::goog_highpass_filter,
          &MediaTrackConstraintSetPlatform::goog_experimental_auto_gain_control,
      };

  ASSERT_EQ(kAudioProcessingProperties.size(),
            kAudioProcessingConstraints.size());
  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (size_t i = 0; i < kAudioProcessingProperties.size(); ++i) {
        for (bool value : kBoolValues) {
          ResetFactory();
          (((constraint_factory_.*accessor)().*kAudioProcessingConstraints[i]).*
           set_function)(value);
          auto result = SelectSettings();
          EXPECT_TRUE(result.HasValue());
          EXPECT_EQ(value, result.audio_processing_properties().*
                               kAudioProcessingProperties[i]);
          CheckAllDefaults(AudioSettingsBoolMembers(),
                           {kAudioProcessingProperties[i]}, result);
        }
      }
    }
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, SampleSize) {
  ResetFactory();
  constraint_factory_.basic().sample_size.SetExact(16);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetExact(0);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Only set a min value for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_size.SetMin(16);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetMin(17);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Only set a max value for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_size.SetMax(16);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetMax(15);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Define a bounded range for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_size.SetMin(10);
  constraint_factory_.basic().sample_size.SetMax(20);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetMin(-10);
  constraint_factory_.basic().sample_size.SetMax(10);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetMin(20);
  constraint_factory_.basic().sample_size.SetMax(30);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test ideal constraints.
  ResetFactory();
  constraint_factory_.basic().sample_size.SetIdeal(16);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  ResetFactory();
  constraint_factory_.basic().sample_size.SetIdeal(0);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
}

TEST_P(MediaStreamConstraintsUtilAudioTest, Channels) {
  int channel_count = kMinChannels;
  AudioCaptureSettings result;

  // Test set exact channelCount.
  for (; channel_count <= media::limits::kMaxChannels; ++channel_count) {
    ResetFactory();
    constraint_factory_.basic().channel_count.SetExact(channel_count);
    result = SelectSettings();

    if (!IsDeviceCapture()) {
      // The source capture configured above is actually using a channel count
      // set to 2 channels.
      if (channel_count <= 2)
        EXPECT_TRUE(result.HasValue());
      else
        EXPECT_FALSE(result.HasValue());
      continue;
    }

    if (channel_count == 3 || channel_count > 4) {
      EXPECT_FALSE(result.HasValue());
      continue;
    }

    EXPECT_TRUE(result.HasValue());
    if (channel_count == 4)
      EXPECT_EQ(result.device_id(), "4_channels_device");
    else
      EXPECT_EQ(result.device_id(), "default_device");
  }

  // Only set a min value for the constraint.
  ResetFactory();
  constraint_factory_.basic().channel_count.SetMin(media::limits::kMaxChannels +
                                                   1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().channel_count.SetMin(kMinChannels);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  // Only set a max value for the constraint.
  ResetFactory();
  constraint_factory_.basic().channel_count.SetMax(kMinChannels - 1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().channel_count.SetMax(kMinChannels);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  // Define a bounded range for the constraint.
  ResetFactory();
  constraint_factory_.basic().channel_count.SetMin(kMinChannels);
  constraint_factory_.basic().channel_count.SetMax(media::limits::kMaxChannels);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().channel_count.SetMin(kMinChannels - 10);
  constraint_factory_.basic().channel_count.SetMax(kMinChannels - 1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().channel_count.SetMin(media::limits::kMaxChannels +
                                                   1);
  constraint_factory_.basic().channel_count.SetMax(media::limits::kMaxChannels +
                                                   10);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test ideal constraints.
  for (; channel_count <= media::limits::kMaxChannels; ++channel_count) {
    ResetFactory();
    constraint_factory_.basic().channel_count.SetExact(channel_count);
    result = SelectSettings();

    EXPECT_TRUE(result.HasValue());
    if (IsDeviceCapture()) {
      if (channel_count == 4)
        EXPECT_EQ(result.device_id(), "4_channels_device");
      else
        EXPECT_EQ(result.device_id(), "default_device");
    }
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, ChannelsWithSource) {
  if (!IsDeviceCapture())
    return;

  std::unique_ptr<blink::LocalMediaStreamAudioSource> source =
      GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */,
                                     false /* disable_local_echo */,
                                     false /* render_to_associated_sink */);
  int channel_count = kMinChannels;
  for (; channel_count <= media::limits::kMaxChannels; ++channel_count) {
    ResetFactory();
    constraint_factory_.basic().channel_count.SetExact(channel_count);
    auto result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    if (channel_count == 2)
      EXPECT_TRUE(result.HasValue());
    else
      EXPECT_FALSE(result.HasValue());
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRate) {
  AudioCaptureSettings result;
  int exact_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
  int min_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
  // |max_sample_rate| is different based on architecture, namely due to a
  // difference on Android.
  int max_sample_rate =
      std::max(static_cast<int>(media::AudioParameters::kAudioCDSampleRate),
               blink::kAudioProcessingSampleRate);
  int ideal_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
  if (!IsDeviceCapture()) {
    exact_sample_rate = media::AudioParameters::kAudioCDSampleRate;
    min_sample_rate =
        std::min(static_cast<int>(media::AudioParameters::kAudioCDSampleRate),
                 blink::kAudioProcessingSampleRate);
    ideal_sample_rate = media::AudioParameters::kAudioCDSampleRate;
  }

  // Test set exact sampleRate.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetExact(exact_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().sample_rate.SetExact(11111);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Only set a min value for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetMin(max_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "default_device");

  constraint_factory_.basic().sample_rate.SetMin(max_sample_rate + 1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Only set a max value for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetMax(min_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().sample_rate.SetMax(min_sample_rate - 1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Define a bounded range for the constraint.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetMin(min_sample_rate);
  constraint_factory_.basic().sample_rate.SetMax(max_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "default_device");

  constraint_factory_.basic().sample_rate.SetMin(min_sample_rate - 1000);
  constraint_factory_.basic().sample_rate.SetMax(min_sample_rate - 1);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().sample_rate.SetMin(max_sample_rate + 1);
  constraint_factory_.basic().sample_rate.SetMax(max_sample_rate + 1000);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test ideal constraints.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetIdeal(ideal_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().sample_rate.SetIdeal(ideal_sample_rate);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  if (IsDeviceCapture()) {
    constraint_factory_.basic().sample_rate.SetIdeal(
        blink::AudioProcessing::kSampleRate48kHz + 1000);
    result = SelectSettings();
    EXPECT_TRUE(result.HasValue());
    EXPECT_EQ(result.device_id(), "default_device");
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRateWithSource) {
  if (!IsDeviceCapture())
    return;

  std::unique_ptr<blink::LocalMediaStreamAudioSource> source =
      GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */,
                                     false /* disable_local_echo */,
                                     false /* render_to_associated_sink */);

  // Test set exact sampleRate.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetExact(
      media::AudioParameters::kAudioCDSampleRate);
  auto result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().sample_rate.SetExact(11111);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_FALSE(result.HasValue());

  // Test set min sampleRate.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetMin(
      media::AudioParameters::kAudioCDSampleRate);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().sample_rate.SetMin(
      media::AudioParameters::kAudioCDSampleRate + 1);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_FALSE(result.HasValue());

  // Test set max sampleRate.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetMax(
      media::AudioParameters::kAudioCDSampleRate);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().sample_rate.SetMax(
      media::AudioParameters::kAudioCDSampleRate - 1);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_FALSE(result.HasValue());

  // Test set ideal sampleRate.
  ResetFactory();
  constraint_factory_.basic().sample_rate.SetIdeal(
      media::AudioParameters::kAudioCDSampleRate);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().sample_rate.SetIdeal(
      media::AudioParameters::kAudioCDSampleRate - 1);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());
}

TEST_P(MediaStreamConstraintsUtilAudioTest, Latency) {
  // Test set exact sampleRate.
  ResetFactory();
  if (IsDeviceCapture())
    constraint_factory_.basic().latency.SetExact(0.125);
  else
    constraint_factory_.basic().latency.SetExact(0.01);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().latency.SetExact(
      static_cast<double>(blink::kFallbackAudioLatencyMs) / 1000);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "default_device");

  constraint_factory_.basic().latency.SetExact(0.0);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set min sampleRate.
  ResetFactory();
  if (IsDeviceCapture())
    constraint_factory_.basic().latency.SetMin(0.125);
  else
    constraint_factory_.basic().latency.SetMin(0.01);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().latency.SetMin(0.126);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set max sampleRate.
  ResetFactory();
  constraint_factory_.basic().latency.SetMax(0.1);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "default_device");

  constraint_factory_.basic().latency.SetMax(0.001);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set bounded sampleRate range.
  ResetFactory();
  if (IsDeviceCapture()) {
    constraint_factory_.basic().latency.SetMin(0.1);
    constraint_factory_.basic().latency.SetMax(0.125);
  } else {
    constraint_factory_.basic().latency.SetMin(0.01);
    constraint_factory_.basic().latency.SetMax(0.1);
  }
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().latency.SetMin(0.0001);
  constraint_factory_.basic().latency.SetMax(0.001);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().latency.SetMin(0.126);
  constraint_factory_.basic().latency.SetMax(0.2);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set ideal sampleRate range.
  ResetFactory();
  if (IsDeviceCapture())
    constraint_factory_.basic().latency.SetIdeal(0.125);
  else
    constraint_factory_.basic().latency.SetIdeal(0.01);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "8khz_sample_rate_device");

  constraint_factory_.basic().latency.SetIdeal(0.0);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  if (IsDeviceCapture())
    EXPECT_EQ(result.device_id(), "default_device");
}

TEST_P(MediaStreamConstraintsUtilAudioTest, LatencyWithSource) {
  if (!IsDeviceCapture())
    return;

  std::unique_ptr<blink::LocalMediaStreamAudioSource> source =
      GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */,
                                     false /* disable_local_echo */,
                                     false /* render_to_associated_sink */);
  // Test set exact sampleRate.
  ResetFactory();
  constraint_factory_.basic().latency.SetExact(0.01);
  auto result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().latency.SetExact(0.1234);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_FALSE(result.HasValue());

  // Test set min sampleRate.
  ResetFactory();
  constraint_factory_.basic().latency.SetMin(0.01);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().latency.SetMin(0.2);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set max sampleRate.
  ResetFactory();
  constraint_factory_.basic().latency.SetMax(
      static_cast<double>(blink::kFallbackAudioLatencyMs) / 1000);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().latency.SetMax(0.001);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set bounded sampleRate range.
  ResetFactory();
  constraint_factory_.basic().latency.SetMin(0.01);
  constraint_factory_.basic().latency.SetMax(0.1);
  result = SelectSettings();
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().latency.SetMin(0.0001);
  constraint_factory_.basic().latency.SetMax(0.001);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  constraint_factory_.basic().latency.SetMin(0.2);
  constraint_factory_.basic().latency.SetMax(0.4);
  result = SelectSettings();
  EXPECT_FALSE(result.HasValue());

  // Test set ideal sampleRate.
  ResetFactory();
  constraint_factory_.basic().latency.SetIdeal(0.01);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.basic().latency.SetIdeal(0.1234);
  result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());
}

// DeviceID tests.
TEST_P(MediaStreamConstraintsUtilAudioTest, ExactArbitraryDeviceID) {
  const String kArbitraryDeviceID = "arbitrary";
  constraint_factory_.basic().device_id.SetExact(kArbitraryDeviceID);
  auto result = SelectSettings();
  // kArbitraryDeviceID is invalid for device capture, but it is considered
  // valid for content capture. For content capture, validation of device
  // capture is performed by the getUserMedia() implementation.
  if (IsDeviceCapture()) {
    EXPECT_FALSE(result.HasValue());
    EXPECT_EQ(std::string(constraint_factory_.basic().device_id.GetName()),
              std::string(result.failed_constraint_name()));
  } else {
    EXPECT_TRUE(result.HasValue());
    EXPECT_EQ(kArbitraryDeviceID.Utf8(), result.device_id());
    CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
                      result);
    CheckEchoCancellationTypeDefault(result);
  }
}

// DeviceID tests check various ways to deal with the device_id constraint.
TEST_P(MediaStreamConstraintsUtilAudioTest, IdealArbitraryDeviceID) {
  const String kArbitraryDeviceID = "arbitrary";
  constraint_factory_.basic().device_id.SetIdeal(kArbitraryDeviceID);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  // kArbitraryDeviceID is invalid for device capture, but it is considered
  // valid for content capture. For content capture, validation of device
  // capture is performed by the getUserMedia() implementation.
  if (IsDeviceCapture())
    CheckDeviceDefaults(result);
  else
    EXPECT_EQ(kArbitraryDeviceID.Utf8(), result.device_id());
  CheckProcessingType(result);
  CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
                    result);
  CheckEchoCancellationTypeDefault(result);
}

TEST_P(MediaStreamConstraintsUtilAudioTest, ExactValidDeviceID) {
  for (const auto& device : capabilities_) {
    constraint_factory_.basic().device_id.SetExact(device.DeviceID());
    auto result = SelectSettings();
    EXPECT_TRUE(result.HasValue());
    CheckDevice(device, result);
    CheckProcessingType(result);
    CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
                      result);
    EchoCancellationType expected_echo_cancellation_type =
        EchoCancellationType::kEchoCancellationDisabled;
    if (IsDeviceCapture()) {
      const bool has_system_echo_cancellation =
          device.Parameters().effects() &
          media::AudioParameters::ECHO_CANCELLER;
      expected_echo_cancellation_type =
          has_system_echo_cancellation
              ? EchoCancellationType::kEchoCancellationSystem
              : EchoCancellationType::kEchoCancellationAec3;
    }
    EXPECT_EQ(expected_echo_cancellation_type,
              result.audio_processing_properties().echo_cancellation_type);
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, ExactGroupID) {
  for (const auto& device : capabilities_) {
    constraint_factory_.basic().group_id.SetExact(device.GroupID());
    auto result = SelectSettings();
    EXPECT_TRUE(result.HasValue());
    CheckDevice(device, result);
    CheckProcessingType(result);
    CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
                      result);
    EchoCancellationType expected_echo_cancellation_type =
        EchoCancellationType::kEchoCancellationDisabled;
    if (IsDeviceCapture()) {
      const bool has_system_echo_cancellation =
          device.Parameters().effects() &
          media::AudioParameters::ECHO_CANCELLER;
      expected_echo_cancellation_type =
          has_system_echo_cancellation
              ? EchoCancellationType::kEchoCancellationSystem
              : EchoCancellationType::kEchoCancellationAec3;
    }
    EXPECT_EQ(expected_echo_cancellation_type,
              result.audio_processing_properties().echo_cancellation_type);
  }
}

// Tests the echoCancellation constraint with a device without system echo
// cancellation.
TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithWebRtc) {
  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (bool value : kBoolValues) {
        ResetFactory();
        ((constraint_factory_.*accessor)().echo_cancellation.*
         set_function)(value);
        auto result = SelectSettings();
        EXPECT_TRUE(result.HasValue());
        const AudioProcessingProperties& properties =
            result.audio_processing_properties();
        // With device capture, the echo_cancellation constraint
        // enables/disables all audio processing by default.
        // With content capture, the echo_cancellation constraint controls
        // only the echo_cancellation properties. The other audio processing
        // properties default to false.
        const EchoCancellationType expected_echo_cancellation_type =
            value ? EchoCancellationType::kEchoCancellationAec3
                  : EchoCancellationType::kEchoCancellationDisabled;
        EXPECT_EQ(expected_echo_cancellation_type,
                  properties.echo_cancellation_type);
        const bool enable_webrtc_audio_processing =
            IsDeviceCapture() ? value : false;
        EXPECT_EQ(enable_webrtc_audio_processing,
                  properties.goog_auto_gain_control);
        CheckGoogExperimentalEchoCancellationDefault(
            properties, enable_webrtc_audio_processing);
        EXPECT_EQ(enable_webrtc_audio_processing,
                  properties.goog_noise_suppression);
        EXPECT_EQ(enable_webrtc_audio_processing,
                  properties.goog_experimental_noise_suppression);
        EXPECT_EQ(enable_webrtc_audio_processing,
                  properties.goog_highpass_filter);
        EXPECT_EQ(enable_webrtc_audio_processing,
                  properties.goog_experimental_auto_gain_control);

        // The following are not audio processing.
        EXPECT_FALSE(properties.goog_audio_mirroring);
        EXPECT_EQ(GetMediaStreamSource() != blink::kMediaStreamSourceDesktop,
                  result.disable_local_echo());
        EXPECT_FALSE(result.render_to_associated_sink());
        CheckProcessingType(result);
        if (IsDeviceCapture()) {
          CheckDevice(*default_device_, result);
        } else {
          EXPECT_TRUE(result.device_id().empty());
        }
      }
    }
  }
}

// Tests the echoCancellation constraint with a device with system echo
// cancellation.
TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSystem) {
  // With content capture, there is no system echo cancellation, so
  // nothing to test.
  if (!IsDeviceCapture())
    return;

  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (bool value : kBoolValues) {
        ResetFactory();
        constraint_factory_.basic().device_id.SetExact(
            system_echo_canceller_device_->DeviceID());
        ((constraint_factory_.*accessor)().echo_cancellation.*
         set_function)(value);
        auto result = SelectSettings();
        EXPECT_TRUE(result.HasValue());
        const AudioProcessingProperties& properties =
            result.audio_processing_properties();
        // With system echo cancellation, the echo_cancellation constraint
        // enables/disables all audio processing by default, WebRTC echo
        // cancellation is always disabled, and system echo cancellation is
        // disabled if the echo_cancellation constraint is false.
        const EchoCancellationType expected_echo_cancellation_type =
            value ? EchoCancellationType::kEchoCancellationSystem
                  : EchoCancellationType::kEchoCancellationDisabled;
        EXPECT_EQ(expected_echo_cancellation_type,
                  properties.echo_cancellation_type);
        EXPECT_EQ(value, properties.goog_auto_gain_control);
        CheckGoogExperimentalEchoCancellationDefault(properties, value);
        EXPECT_EQ(value, properties.goog_noise_suppression);
        EXPECT_EQ(value, properties.goog_experimental_noise_suppression);
        EXPECT_EQ(value, properties.goog_highpass_filter);
        EXPECT_EQ(value, properties.goog_experimental_auto_gain_control);

        // The following are not audio processing.
        EXPECT_FALSE(properties.goog_audio_mirroring);
        EXPECT_EQ(GetMediaStreamSource() != blink::kMediaStreamSourceDesktop,
                  result.disable_local_echo());
        EXPECT_FALSE(result.render_to_associated_sink());
        CheckProcessingType(result);
        CheckDevice(*system_echo_canceller_device_, result);
      }
    }
  }
}

// Tests the googEchoCancellation constraint with a device without system echo
// cancellation.
TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithWebRtc) {
  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointers due to the comparison failing
      // on compilers.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (bool value : kBoolValues) {
        ResetFactory();
        ((constraint_factory_.*accessor)().goog_echo_cancellation.*
         set_function)(value);
        auto result = SelectSettings();
        EXPECT_TRUE(result.HasValue());
        const AudioProcessingProperties& properties =
            result.audio_processing_properties();
        // The goog_echo_cancellation constraint controls only the
        // echo_cancellation properties. The other audio processing properties
        // use the default values.
        const EchoCancellationType expected_echo_cancellation_type =
            value ? EchoCancellationType::kEchoCancellationAec3
                  : EchoCancellationType::kEchoCancellationDisabled;
        EXPECT_EQ(expected_echo_cancellation_type,
                  properties.echo_cancellation_type);
        CheckProcessingType(result);
        CheckBoolDefaults(AudioSettingsBoolMembers(),
                          AudioPropertiesBoolMembers(), result);
        if (IsDeviceCapture()) {
          CheckDevice(*default_device_, result);
        } else {
          EXPECT_TRUE(result.device_id().empty());
        }
      }
    }
  }
}

// Tests the googEchoCancellation constraint with a device with system echo
// cancellation.
TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSystem) {
  // With content capture, there is no system echo cancellation, so
  // nothing to test.
  if (!IsDeviceCapture())
    return;

  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (bool value : kBoolValues) {
        ResetFactory();
        constraint_factory_.basic().device_id.SetExact(
            system_echo_canceller_device_->DeviceID());
        ((constraint_factory_.*accessor)().goog_echo_cancellation.*
         set_function)(value);
        auto result = SelectSettings();
        EXPECT_TRUE(result.HasValue());
        const AudioProcessingProperties& properties =
            result.audio_processing_properties();
        // With system echo cancellation, WebRTC echo cancellation is always
        // disabled, and system echo cancellation is disabled if
        // goog_echo_cancellation is false.
        const EchoCancellationType expected_echo_cancellation_type =
            value ? EchoCancellationType::kEchoCancellationSystem
                  : EchoCancellationType::kEchoCancellationDisabled;
        EXPECT_EQ(expected_echo_cancellation_type,
                  properties.echo_cancellation_type);
        CheckProcessingType(result);
        CheckBoolDefaults(AudioSettingsBoolMembers(),
                          AudioPropertiesBoolMembers(), result);
        CheckDevice(*system_echo_canceller_device_, result);
      }
    }
  }
}

// Test that having differing mandatory values for echoCancellation and
// googEchoCancellation fails.
TEST_P(MediaStreamConstraintsUtilAudioTest, ContradictoryEchoCancellation) {
  for (bool value : kBoolValues) {
    constraint_factory_.basic().echo_cancellation.SetExact(value);
    constraint_factory_.basic().goog_echo_cancellation.SetExact(!value);
    auto result = SelectSettings();
    EXPECT_FALSE(result.HasValue());
    EXPECT_EQ(result.failed_constraint_name(),
              constraint_factory_.basic().echo_cancellation.GetName());
  }
}

// Test that having differing mandatory values for googAutoGainControl and
// googAutoGainControl2 fails. This test is valid to correctly support the
// old syntax.
TEST_P(MediaStreamConstraintsUtilAudioTest, ContradictoryAutoGainControl) {
  // TODO(armax): fix this.
  for (bool value : kBoolValues) {
    constraint_factory_.basic().goog_auto_gain_control.SetExact(value);
    constraint_factory_.basic().goog_experimental_auto_gain_control.SetExact(
        !value);
    auto result = SelectSettings();
    EXPECT_FALSE(result.HasValue());
    EXPECT_EQ(result.failed_constraint_name(),
              constraint_factory_.basic()
                  .goog_experimental_auto_gain_control.GetName());
  }
}

// Tests that individual boolean audio-processing constraints override the
// default value set by the echoCancellation constraint.
TEST_P(MediaStreamConstraintsUtilAudioTest,
       EchoCancellationAndSingleBoolConstraint) {
  const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
      kAudioProcessingConstraints = {
          &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
          &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
          &MediaTrackConstraintSetPlatform::goog_experimental_echo_cancellation,
          &MediaTrackConstraintSetPlatform::goog_noise_suppression,
          &MediaTrackConstraintSetPlatform::goog_experimental_noise_suppression,
          &MediaTrackConstraintSetPlatform::goog_highpass_filter,
          &MediaTrackConstraintSetPlatform::goog_experimental_auto_gain_control,
      };

  ASSERT_EQ(kAudioProcessingProperties.size(),
            kAudioProcessingConstraints.size());
  for (auto set_function : kBoolSetFunctions) {
    for (auto accessor : kFactoryAccessors) {
      // Ideal advanced is ignored by the SelectSettings algorithm.
      // Using array elements instead of pointer values due to the comparison
      // failing on some build configurations.
      if (set_function == kBoolSetFunctions[1] &&
          accessor == kFactoryAccessors[1]) {
        continue;
      }
      for (size_t i = 0; i < kAudioProcessingProperties.size(); ++i) {
        ResetFactory();
        ((constraint_factory_.*accessor)().echo_cancellation.*
         set_function)(false);
        (((constraint_factory_.*accessor)().*kAudioProcessingConstraints[i]).*
         set_function)(true);
        auto result = SelectSettings();
        EXPECT_TRUE(result.HasValue());
        CheckProcessingType(result);
        EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
                  result.audio_processing_properties().echo_cancellation_type);
        EXPECT_TRUE(result.audio_processing_properties().*
                    kAudioProcessingProperties[i]);
        for (size_t j = 0; j < kAudioProcessingProperties.size(); ++j) {
          if (i == j)
            continue;
          // goog_auto_gain_control and goog_experimental_auto_gain_control
          // should always match in value.
          if ((i == 1 && j == 6) || (i == 6 && j == 1)) {
            EXPECT_EQ(result.audio_processing_properties().*
                          kAudioProcessingProperties[i],
                      result.audio_processing_properties().*
                          kAudioProcessingProperties[j]);
            continue;
          }
          EXPECT_FALSE(result.audio_processing_properties().*
                       kAudioProcessingProperties[j]);
        }
      }
    }
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest,
       ReconfigurationSystemEchoCancellation) {
  // This test is relevant only for device capture, where HW EC can be found.
  if (!IsDeviceCapture())
    return;

  // Create a capability that is based on a already opened source with system
  // echo cancellation enabled.
  AudioProcessingProperties properties;
  properties.echo_cancellation_type =
      EchoCancellationType::kEchoCancellationSystem;
  std::unique_ptr<ProcessedLocalAudioSource> system_echo_canceller_source =
      GetProcessedLocalAudioSource(
          properties, false /* disable_local_echo */,
          false /* render_to_associated_sink */,
          media::AudioParameters::PlatformEffectsMask::ECHO_CANCELLER);
  AudioDeviceCaptureCapabilities capabilities = {
      AudioDeviceCaptureCapability(system_echo_canceller_source.get())};
  AudioDeviceCaptureCapability* system_echo_canceller_with_source =
      &capabilities[0];

  constraint_factory_.Reset();
  constraint_factory_.basic().device_id.SetExact(
      system_echo_canceller_with_source->DeviceID());
  constraint_factory_.basic().echo_cancellation.SetExact(true);
  auto result = SelectSettings(true, capabilities);
  EXPECT_TRUE(result.HasValue());

  constraint_factory_.Reset();
  constraint_factory_.basic().device_id.SetExact(
      system_echo_canceller_with_source->DeviceID());
  constraint_factory_.basic().echo_cancellation.SetExact(false);
  result = SelectSettings(true, capabilities);
  EXPECT_FALSE(result.HasValue());
}

// Test advanced constraints sets that can be satisfied.
TEST_P(MediaStreamConstraintsUtilAudioTest, AdvancedCompatibleConstraints) {
  constraint_factory_.AddAdvanced().render_to_associated_sink.SetExact(true);
  constraint_factory_.AddAdvanced().goog_audio_mirroring.SetExact(true);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  CheckDeviceDefaults(result);
  CheckProcessingType(result);
  CheckBoolDefaults({&AudioCaptureSettings::render_to_associated_sink},
                    {&AudioProcessingProperties::goog_audio_mirroring}, result);
  CheckEchoCancellationTypeDefault(result);
  EXPECT_TRUE(result.render_to_associated_sink());
  EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
}

// Test that an advanced constraint set that contradicts a previous constraint
// set is ignored, but that further constraint sets that can be satisfied are
// applied.
TEST_P(MediaStreamConstraintsUtilAudioTest,
       AdvancedConflictingMiddleConstraints) {
  constraint_factory_.AddAdvanced().goog_highpass_filter.SetExact(true);
  auto& advanced2 = constraint_factory_.AddAdvanced();
  advanced2.goog_highpass_filter.SetExact(false);
  constraint_factory_.AddAdvanced().goog_audio_mirroring.SetExact(true);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  CheckProcessingType(result);
  CheckDeviceDefaults(result);
  CheckBoolDefaults({},
                    {&AudioProcessingProperties::goog_audio_mirroring,
                     &AudioProcessingProperties::goog_highpass_filter},
                    result);
  CheckEchoCancellationTypeDefault(result);
  EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
  EXPECT_TRUE(result.audio_processing_properties().goog_highpass_filter);
}

// Test that an advanced constraint set that contradicts a previous constraint
// set with a boolean constraint is ignored.
TEST_P(MediaStreamConstraintsUtilAudioTest, AdvancedConflictingLastConstraint) {
  constraint_factory_.AddAdvanced().goog_highpass_filter.SetExact(true);
  constraint_factory_.AddAdvanced().goog_audio_mirroring.SetExact(true);
  auto result = SelectSettings();
  EXPECT_TRUE(result.HasValue());
  CheckProcessingType(result);
  CheckDeviceDefaults(result);
  CheckBoolDefaults({},
                    {&AudioProcessingProperties::goog_audio_mirroring,
                     &AudioProcessingProperties::goog_highpass_filter},
                    result);
  CheckEchoCancellationTypeDefault(result);
  // The fourth advanced set is ignored because it contradicts the second set.
  EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
  EXPECT_TRUE(result.audio_processing_properties().goog_highpass_filter);
}

// NoDevices tests verify that the case with no devices is handled correctly.
TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesNoConstraints) {
  // This test makes sense only for device capture.
  if (!IsDeviceCapture())
    return;

  AudioDeviceCaptureCapabilities capabilities;
  auto result = SelectSettingsAudioCapture(
      capabilities, constraint_factory_.CreateMediaConstraints(), false);
  EXPECT_FALSE(result.HasValue());
  EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}

TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesWithConstraints) {
  // This test makes sense only for device capture.
  if (!IsDeviceCapture())
    return;

  AudioDeviceCaptureCapabilities capabilities;
  constraint_factory_.basic().sample_size.SetExact(16);
  auto result = SelectSettingsAudioCapture(
      capabilities, constraint_factory_.CreateMediaConstraints(), false);
  EXPECT_FALSE(result.HasValue());
  EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}

// Test functionality to support applyConstraints() for tracks attached to
// sources that have no audio processing.
TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithNoAudioProcessing) {
  for (bool enable_properties : {true, false}) {
    std::unique_ptr<blink::LocalMediaStreamAudioSource> source =
        GetLocalMediaStreamAudioSource(
            enable_properties /* enable_system_echo_canceller */,
            enable_properties /* disable_local_echo */,
            enable_properties /* render_to_associated_sink */);

    // These constraints are false in |source|.
    const std::vector<
        blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
        kConstraints = {
            &MediaTrackConstraintSetPlatform::echo_cancellation,
            &MediaTrackConstraintSetPlatform::disable_local_echo,
            &MediaTrackConstraintSetPlatform::render_to_associated_sink,
        };

    for (size_t i = 0; i < kConstraints.size(); ++i) {
      constraint_factory_.Reset();
      (constraint_factory_.basic().*kConstraints[i])
          .SetExact(enable_properties);
      auto result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kConstraints[i])
          .SetExact(!enable_properties);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_FALSE(result.HasValue());

      // Setting just ideal values should always succeed.
      constraint_factory_.Reset();
      (constraint_factory_.basic().*kConstraints[i]).SetIdeal(true);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kConstraints[i]).SetIdeal(false);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());
    }
  }
}

// Test functionality to support applyConstraints() for tracks attached to
// sources that have audio processing.
TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
  // Processed audio sources are supported only for device capture.
  if (!IsDeviceCapture())
    return;

  for (bool use_defaults : {true, false}) {
    AudioProcessingProperties properties;
    if (!use_defaults) {
      properties.echo_cancellation_type =
          EchoCancellationType::kEchoCancellationDisabled;
      properties.goog_audio_mirroring = !properties.goog_audio_mirroring;
      properties.goog_auto_gain_control = !properties.goog_auto_gain_control;
      properties.goog_experimental_echo_cancellation =
          !properties.goog_experimental_echo_cancellation;
      properties.goog_noise_suppression = !properties.goog_noise_suppression;
      properties.goog_experimental_noise_suppression =
          !properties.goog_experimental_noise_suppression;
      properties.goog_highpass_filter = !properties.goog_highpass_filter;
      properties.goog_experimental_auto_gain_control =
          !properties.goog_experimental_auto_gain_control;
    }

    std::unique_ptr<ProcessedLocalAudioSource> source =
        GetProcessedLocalAudioSource(
            properties, use_defaults /* disable_local_echo */,
            use_defaults /* render_to_associated_sink */);
    const std::vector<
        blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
        kAudioProcessingConstraints = {
            &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
            &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
            &MediaTrackConstraintSetPlatform::
                goog_experimental_echo_cancellation,
            &MediaTrackConstraintSetPlatform::goog_noise_suppression,
            &MediaTrackConstraintSetPlatform::
                goog_experimental_noise_suppression,
            &MediaTrackConstraintSetPlatform::goog_highpass_filter,
            &MediaTrackConstraintSetPlatform::
                goog_experimental_auto_gain_control,
        };
    ASSERT_EQ(kAudioProcessingConstraints.size(),
              kAudioProcessingProperties.size());

    for (size_t i = 0; i < kAudioProcessingConstraints.size(); ++i) {
      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioProcessingConstraints[i])
          .SetExact(properties.*kAudioProcessingProperties[i]);
      auto result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioProcessingConstraints[i])
          .SetExact(!(properties.*kAudioProcessingProperties[i]));
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_FALSE(result.HasValue());

      // Setting just ideal values should always succeed.
      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioProcessingConstraints[i])
          .SetIdeal(true);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioProcessingConstraints[i])
          .SetIdeal(false);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());
    }

    // Test same as above but for echo cancellation.
    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(
        properties.echo_cancellation_type ==
        EchoCancellationType::kEchoCancellationAec3);
    auto result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(
        properties.echo_cancellation_type !=
        EchoCancellationType::kEchoCancellationAec3);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_FALSE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetIdeal(true);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetIdeal(false);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());

    // These constraints are false in |source|.
    const std::vector<
        blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
        kAudioBrowserConstraints = {
            &MediaTrackConstraintSetPlatform::disable_local_echo,
            &MediaTrackConstraintSetPlatform::render_to_associated_sink,
        };
    for (size_t i = 0; i < kAudioBrowserConstraints.size(); ++i) {
      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioBrowserConstraints[i])
          .SetExact(use_defaults);
      auto result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioBrowserConstraints[i])
          .SetExact(!use_defaults);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_FALSE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioBrowserConstraints[i]).SetIdeal(true);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());

      constraint_factory_.Reset();
      (constraint_factory_.basic().*kAudioBrowserConstraints[i])
          .SetIdeal(false);
      result = SelectSettingsAudioCapture(
          source.get(), constraint_factory_.CreateMediaConstraints());
      EXPECT_TRUE(result.HasValue());
    }

    // Test same as above for echo cancellation.
    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(use_defaults);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(!use_defaults);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_FALSE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetIdeal(true);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());

    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetIdeal(false);
    result = SelectSettingsAudioCapture(
        source.get(), constraint_factory_.CreateMediaConstraints());
    EXPECT_TRUE(result.HasValue());
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
  // The distinction of used and unused sources is relevant only for device
  // capture.
  if (!IsDeviceCapture())
    return;

  AudioProcessingProperties properties;
  std::unique_ptr<ProcessedLocalAudioSource> processed_source =
      GetProcessedLocalAudioSource(properties, false /* disable_local_echo */,
                                   false /* render_to_associated_sink */);

  const String kUnusedDeviceID = "unused_device";
  const String kGroupID = "fake_group";
  AudioDeviceCaptureCapabilities capabilities;
  capabilities.emplace_back(processed_source.get());
  capabilities.emplace_back(kUnusedDeviceID, kGroupID,
                            media::AudioParameters::UnavailableDeviceParams());

  {
    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(false);

    auto result = SelectSettingsAudioCapture(
        capabilities, constraint_factory_.CreateMediaConstraints(),
        false /* should_disable_hardware_noise_suppression */);
    EXPECT_TRUE(result.HasValue());
    EXPECT_EQ(result.device_id(), kUnusedDeviceID.Utf8());
    EXPECT_EQ(result.audio_processing_properties().echo_cancellation_type,
              EchoCancellationType::kEchoCancellationDisabled);
  }

  {
    constraint_factory_.Reset();
    constraint_factory_.basic().echo_cancellation.SetExact(true);
    auto result = SelectSettingsAudioCapture(
        capabilities, constraint_factory_.CreateMediaConstraints(),
        false /* should_disable_hardware_noise_suppression */);
    EXPECT_TRUE(result.HasValue());
    EXPECT_EQ(result.device_id(), processed_source->device().id);
    EXPECT_EQ(result.audio_processing_properties().echo_cancellation_type,
              EchoCancellationType::kEchoCancellationAec3);
  }
}

TEST_P(MediaStreamConstraintsUtilAudioTest, ExperimetanlEcWithSource) {
  std::unique_ptr<blink::LocalMediaStreamAudioSource> source =
      GetLocalMediaStreamAudioSource(
          false /* enable_system_echo_canceller */,
          false /* disable_local_echo */, false /* render_to_associated_sink */,
          true /* enable_experimental_echo_canceller */);

  constraint_factory_.Reset();
  constraint_factory_.basic().echo_cancellation.SetExact(false);

  auto result = SelectSettingsAudioCapture(
      source.get(), constraint_factory_.CreateMediaConstraints());
  EXPECT_TRUE(result.HasValue());
}

TEST_P(MediaStreamConstraintsUtilAudioTest, LatencyConstraint) {
  if (!IsDeviceCapture())
    return;

  // The minimum is 10ms because the AudioParameters used in
  // GetLocalMediaStreamAudioSource() device.input come from the default
  // constructor to blink::MediaStreamDevice, which sets them to
  // AudioParameters::UnavailableDeviceParams(), which uses a 10ms buffer size.
  double default_device_min =
      10 / static_cast<double>(base::Time::kMillisecondsPerSecond);
  double default_device_max =
      1000 / static_cast<double>(media::AudioParameters::kAudioCDSampleRate);

  CheckLatencyConstraint(default_device_, default_device_min,
                         default_device_max);
  CheckLocalMediaStreamAudioSourceLatency(
      default_device_, 0.003,
      default_device_min *
          static_cast<double>(media::AudioParameters::kAudioCDSampleRate));
  CheckLocalMediaStreamAudioSourceLatency(
      default_device_, 0.015,
      default_device_min *
          static_cast<double>(media::AudioParameters::kAudioCDSampleRate));
  CheckLocalMediaStreamAudioSourceLatency(default_device_, 0.022, 1000);
  CheckLocalMediaStreamAudioSourceLatency(default_device_, 0.04, 1000);

  double variable_latency_device_min =
      128 / static_cast<double>(media::AudioParameters::kAudioCDSampleRate);
  double variable_latency_device_max =
      4096 / static_cast<double>(media::AudioParameters::kAudioCDSampleRate);

  CheckLatencyConstraint(variable_latency_device_, variable_latency_device_min,
                         variable_latency_device_max);

  // Values here are the closest match to the requested latency as returned by
  // media::AudioLatency::GetExactBufferSize().
  CheckLocalMediaStreamAudioSourceLatency(variable_latency_device_, 0.001, 128);
  CheckLocalMediaStreamAudioSourceLatency(variable_latency_device_, 0.011, 512);
#if defined(OS_WIN)
  // Windows only uses exactly the minimum or else multiples of the
  // hardware_buffer_size (512 for the variable_latency_device_).
  CheckLocalMediaStreamAudioSourceLatency(variable_latency_device_, 0.020,
                                          1024);
#else
  CheckLocalMediaStreamAudioSourceLatency(variable_latency_device_, 0.020, 896);
#endif
  CheckLocalMediaStreamAudioSourceLatency(variable_latency_device_, 0.2, 4096);
}

INSTANTIATE_TEST_SUITE_P(All,
                         MediaStreamConstraintsUtilAudioTest,
                         testing::Values("",
                                         blink::kMediaStreamSourceTab,
                                         blink::kMediaStreamSourceSystem,
                                         blink::kMediaStreamSourceDesktop));
}  // namespace blink
