/*
 *  Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "media/engine/webrtc_voice_engine.h"

#include <memory>
#include <utility>

#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/transport/field_trial_based_config.h"
#include "call/call.h"
#include "media/base/fake_media_engine.h"
#include "media/base/fake_network_interface.h"
#include "media/base/fake_rtp.h"
#include "media/base/media_constants.h"
#include "media/engine/fake_webrtc_call.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
#include "test/mock_audio_encoder_factory.h"

using ::testing::_;
using ::testing::ContainerEq;
using ::testing::Contains;
using ::testing::Field;
using ::testing::Return;
using ::testing::ReturnPointee;
using ::testing::SaveArg;
using ::testing::StrictMock;

namespace {
using webrtc::BitrateConstraints;

constexpr uint32_t kMaxUnsignaledRecvStreams = 4;

const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
const cricket::AudioCodec kRed48000Codec(112, "RED", 48000, 32000, 2);
const cricket::AudioCodec kTelephoneEventCodec1(106,
                                                "telephone-event",
                                                8000,
                                                0,
                                                1);
const cricket::AudioCodec kTelephoneEventCodec2(107,
                                                "telephone-event",
                                                32000,
                                                0,
                                                1);

const uint32_t kSsrc0 = 0;
const uint32_t kSsrc1 = 1;
const uint32_t kSsrcX = 0x99;
const uint32_t kSsrcY = 0x17;
const uint32_t kSsrcZ = 0x42;
const uint32_t kSsrcW = 0x02;
const uint32_t kSsrcs4[] = {11, 200, 30, 44};

constexpr int kRtpHistoryMs = 5000;

constexpr webrtc::AudioProcessing::Config::GainController1::Mode
    kDefaultAgcMode =
#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
        webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
#else
        webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
#endif

constexpr webrtc::AudioProcessing::Config::NoiseSuppression::Level
    kDefaultNsLevel =
        webrtc::AudioProcessing::Config::NoiseSuppression::Level::kHigh;

void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
  RTC_DCHECK(adm);

  // Setup.
  EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
  EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
#if defined(WEBRTC_WIN)
  EXPECT_CALL(
      *adm,
      SetPlayoutDevice(
          ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
              webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
      .WillOnce(Return(0));
#else
  EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
#endif  // #if defined(WEBRTC_WIN)
  EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
  EXPECT_CALL(*adm, StereoPlayoutIsAvailable(::testing::_)).WillOnce(Return(0));
  EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
#if defined(WEBRTC_WIN)
  EXPECT_CALL(
      *adm,
      SetRecordingDevice(
          ::testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
              webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
      .WillOnce(Return(0));
#else
  EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
#endif  // #if defined(WEBRTC_WIN)
  EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
  EXPECT_CALL(*adm, StereoRecordingIsAvailable(::testing::_))
      .WillOnce(Return(0));
  EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
  EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
  EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
  EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));

  // Teardown.
  EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
  EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
  EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
  EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
}
}  // namespace

// Tests that our stub library "works".
TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
  for (bool use_null_apm : {false, true}) {
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateStrict();
    AdmSetupExpectations(adm);
    rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
        use_null_apm ? nullptr
                     : rtc::make_ref_counted<
                           StrictMock<webrtc::test::MockAudioProcessing>>();

    webrtc::AudioProcessing::Config apm_config;
    if (!use_null_apm) {
      EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
      EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
      EXPECT_CALL(*apm, DetachAecDump());
    }
    {
      webrtc::FieldTrialBasedConfig trials;
      cricket::WebRtcVoiceEngine engine(
          task_queue_factory.get(), adm,
          webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
          webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
          nullptr, trials);
      engine.Init();
    }
  }
}

class FakeAudioSink : public webrtc::AudioSinkInterface {
 public:
  void OnData(const Data& audio) override {}
};

class FakeAudioSource : public cricket::AudioSource {
  void SetSink(Sink* sink) override {}
};

class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam<bool> {
 public:
  WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}

  explicit WebRtcVoiceEngineTestFake(const char* field_trials)
      : use_null_apm_(GetParam()),
        task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
        adm_(webrtc::test::MockAudioDeviceModule::CreateStrict()),
        apm_(use_null_apm_
                 ? nullptr
                 : rtc::make_ref_counted<
                       StrictMock<webrtc::test::MockAudioProcessing>>()),
        call_(),
        override_field_trials_(field_trials) {
    // AudioDeviceModule.
    AdmSetupExpectations(adm_);

    if (!use_null_apm_) {
      // AudioProcessing.
      EXPECT_CALL(*apm_, GetConfig())
          .WillRepeatedly(ReturnPointee(&apm_config_));
      EXPECT_CALL(*apm_, ApplyConfig(_))
          .WillRepeatedly(SaveArg<0>(&apm_config_));
      EXPECT_CALL(*apm_, DetachAecDump());
    }

    // Default Options.
    // TODO(kwiberg): We should use mock factories here, but a bunch of
    // the tests here probe the specific set of codecs provided by the builtin
    // factories. Those tests should probably be moved elsewhere.
    auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
    auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
    engine_.reset(new cricket::WebRtcVoiceEngine(
        task_queue_factory_.get(), adm_, encoder_factory, decoder_factory,
        nullptr, apm_, nullptr, trials_config_));
    engine_->Init();
    send_parameters_.codecs.push_back(kPcmuCodec);
    recv_parameters_.codecs.push_back(kPcmuCodec);

    if (!use_null_apm_) {
      // Default Options.
      VerifyEchoCancellationSettings(/*enabled=*/true);
      EXPECT_TRUE(IsHighPassFilterEnabled());
      EXPECT_TRUE(IsTypingDetectionEnabled());
      EXPECT_TRUE(apm_config_.noise_suppression.enabled);
      EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
      VerifyGainControlEnabledCorrectly();
      VerifyGainControlDefaultSettings();
    }
  }

  bool SetupChannel() {
    channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
                                           cricket::AudioOptions(),
                                           webrtc::CryptoOptions());
    return (channel_ != nullptr);
  }

  bool SetupRecvStream() {
    if (!SetupChannel()) {
      return false;
    }
    return AddRecvStream(kSsrcX);
  }

  bool SetupSendStream() {
    return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
  }

  bool SetupSendStream(const cricket::StreamParams& sp) {
    if (!SetupChannel()) {
      return false;
    }
    if (!channel_->AddSendStream(sp)) {
      return false;
    }
    if (!use_null_apm_) {
      EXPECT_CALL(*apm_, set_output_will_be_muted(false));
    }
    return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
  }

  bool AddRecvStream(uint32_t ssrc) {
    EXPECT_TRUE(channel_);
    return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
  }

  void SetupForMultiSendStream() {
    EXPECT_TRUE(SetupSendStream());
    // Remove stream added in Setup.
    EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
    // Verify the channel does not exist.
    EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
  }

  void DeliverPacket(const void* data, int len) {
    rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
    channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
    rtc::Thread::Current()->ProcessMessages(0);
  }

  void TearDown() override { delete channel_; }

  const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
    const auto* send_stream = call_.GetAudioSendStream(ssrc);
    EXPECT_TRUE(send_stream);
    return *send_stream;
  }

  const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
    const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
    EXPECT_TRUE(recv_stream);
    return *recv_stream;
  }

  const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
    return GetSendStream(ssrc).GetConfig();
  }

  const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
    return GetRecvStream(ssrc).GetConfig();
  }

  void SetSend(bool enable) {
    ASSERT_TRUE(channel_);
    if (enable) {
      EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
      EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
      EXPECT_CALL(*adm_, InitRecording()).WillOnce(Return(0));
    }
    channel_->SetSend(enable);
  }

  void SetSendParameters(const cricket::AudioSendParameters& params) {
    ASSERT_TRUE(channel_);
    EXPECT_TRUE(channel_->SetSendParameters(params));
  }

  void SetAudioSend(uint32_t ssrc,
                    bool enable,
                    cricket::AudioSource* source,
                    const cricket::AudioOptions* options = nullptr) {
    ASSERT_TRUE(channel_);
    if (!use_null_apm_) {
      EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
    }
    EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
  }

  void TestInsertDtmf(uint32_t ssrc,
                      bool caller,
                      const cricket::AudioCodec& codec) {
    EXPECT_TRUE(SetupChannel());
    if (caller) {
      // If this is a caller, local description will be applied and add the
      // send stream.
      EXPECT_TRUE(
          channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
    }

    // Test we can only InsertDtmf when the other side supports telephone-event.
    SetSendParameters(send_parameters_);
    SetSend(true);
    EXPECT_FALSE(channel_->CanInsertDtmf());
    EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
    send_parameters_.codecs.push_back(codec);
    SetSendParameters(send_parameters_);
    EXPECT_TRUE(channel_->CanInsertDtmf());

    if (!caller) {
      // If this is callee, there's no active send channel yet.
      EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
      EXPECT_TRUE(
          channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
    }

    // Check we fail if the ssrc is invalid.
    EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));

    // Test send.
    cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
        GetSendStream(kSsrcX).GetLatestTelephoneEvent();
    EXPECT_EQ(-1, telephone_event.payload_type);
    EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
    telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
    EXPECT_EQ(codec.id, telephone_event.payload_type);
    EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
    EXPECT_EQ(2, telephone_event.event_code);
    EXPECT_EQ(123, telephone_event.duration_ms);
  }

  void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
    // For a caller, the answer will be applied in set remote description
    // where SetSendParameters() is called.
    EXPECT_TRUE(SetupChannel());
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
    send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
    SetSendParameters(send_parameters_);
    const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
    EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
  }

  void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
    // For a callee, the answer will be applied in set local description
    // where SetExtmapAllowMixed() and AddSendStream() are called.
    EXPECT_TRUE(SetupChannel());
    channel_->SetExtmapAllowMixed(extmap_allow_mixed);
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));

    const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
    EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
  }

  // Test that send bandwidth is set correctly.
  // `codec` is the codec under test.
  // `max_bitrate` is a parameter to set to SetMaxSendBandwidth().
  // `expected_result` is the expected result from SetMaxSendBandwidth().
  // `expected_bitrate` is the expected audio bitrate afterward.
  void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
                            int max_bitrate,
                            bool expected_result,
                            int expected_bitrate) {
    cricket::AudioSendParameters parameters;
    parameters.codecs.push_back(codec);
    parameters.max_bandwidth_bps = max_bitrate;
    if (expected_result) {
      SetSendParameters(parameters);
    } else {
      EXPECT_FALSE(channel_->SetSendParameters(parameters));
    }
    EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
  }

  // Sets the per-stream maximum bitrate limit for the specified SSRC.
  bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
    webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
    EXPECT_EQ(1UL, parameters.encodings.size());

    parameters.encodings[0].max_bitrate_bps = bitrate;
    return channel_->SetRtpSendParameters(ssrc, parameters).ok();
  }

  void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
    cricket::AudioSendParameters send_parameters;
    send_parameters.codecs.push_back(codec);
    send_parameters.max_bandwidth_bps = bitrate;
    SetSendParameters(send_parameters);
  }

  void CheckSendCodecBitrate(int32_t ssrc,
                             const char expected_name[],
                             int expected_bitrate) {
    const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
    EXPECT_EQ(expected_name, spec->format.name);
    EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
  }

  absl::optional<int> GetCodecBitrate(int32_t ssrc) {
    return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
  }

  const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
      int32_t ssrc) {
    return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
  }

  void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
                              int global_max,
                              int stream_max,
                              bool expected_result,
                              int expected_codec_bitrate) {
    // Clear the bitrate limit from the previous test case.
    EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));

    // Attempt to set the requested bitrate limits.
    SetGlobalMaxBitrate(codec, global_max);
    EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));

    // Verify that reading back the parameters gives results
    // consistent with the Set() result.
    webrtc::RtpParameters resulting_parameters =
        channel_->GetRtpSendParameters(kSsrcX);
    EXPECT_EQ(1UL, resulting_parameters.encodings.size());
    EXPECT_EQ(expected_result ? stream_max : -1,
              resulting_parameters.encodings[0].max_bitrate_bps);

    // Verify that the codec settings have the expected bitrate.
    EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
  }

  void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
                                          int expected_min_bitrate_bps,
                                          const char* start_bitrate_kbps,
                                          int expected_start_bitrate_bps,
                                          const char* max_bitrate_kbps,
                                          int expected_max_bitrate_bps) {
    EXPECT_TRUE(SetupSendStream());
    auto& codecs = send_parameters_.codecs;
    codecs.clear();
    codecs.push_back(kOpusCodec);
    codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
    codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
    codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
    EXPECT_CALL(*call_.GetMockTransportControllerSend(),
                SetSdpBitrateParameters(
                    AllOf(Field(&BitrateConstraints::min_bitrate_bps,
                                expected_min_bitrate_bps),
                          Field(&BitrateConstraints::start_bitrate_bps,
                                expected_start_bitrate_bps),
                          Field(&BitrateConstraints::max_bitrate_bps,
                                expected_max_bitrate_bps))));

    SetSendParameters(send_parameters_);
  }

  void TestSetSendRtpHeaderExtensions(const std::string& ext) {
    EXPECT_TRUE(SetupSendStream());

    // Ensure extensions are off by default.
    EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure unknown extensions won't cause an error.
    send_parameters_.extensions.push_back(
        webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
    SetSendParameters(send_parameters_);
    EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure extensions stay off with an empty list of headers.
    send_parameters_.extensions.clear();
    SetSendParameters(send_parameters_);
    EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure extension is set properly.
    const int id = 1;
    send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
    SetSendParameters(send_parameters_);
    EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
    EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
    EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);

    // Ensure extension is set properly on new stream.
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
    EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
              call_.GetAudioSendStream(kSsrcY));
    EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
    EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
    EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);

    // Ensure all extensions go back off with an empty list.
    send_parameters_.codecs.push_back(kPcmuCodec);
    send_parameters_.extensions.clear();
    SetSendParameters(send_parameters_);
    EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
    EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
  }

  void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
    EXPECT_TRUE(SetupRecvStream());

    // Ensure extensions are off by default.
    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure unknown extensions won't cause an error.
    recv_parameters_.extensions.push_back(
        webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure extensions stay off with an empty list of headers.
    recv_parameters_.extensions.clear();
    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());

    // Ensure extension is set properly.
    const int id = 2;
    recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
    EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
    EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
    EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);

    // Ensure extension is set properly on new stream.
    EXPECT_TRUE(AddRecvStream(kSsrcY));
    EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
              call_.GetAudioReceiveStream(kSsrcY));
    EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
    EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
    EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);

    // Ensure all extensions go back off with an empty list.
    recv_parameters_.extensions.clear();
    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
  }

  webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
    webrtc::AudioSendStream::Stats stats;
    stats.local_ssrc = 12;
    stats.payload_bytes_sent = 345;
    stats.header_and_padding_bytes_sent = 56;
    stats.packets_sent = 678;
    stats.packets_lost = 9012;
    stats.fraction_lost = 34.56f;
    stats.codec_name = "codec_name_send";
    stats.codec_payload_type = 42;
    stats.jitter_ms = 12;
    stats.rtt_ms = 345;
    stats.audio_level = 678;
    stats.apm_statistics.delay_median_ms = 234;
    stats.apm_statistics.delay_standard_deviation_ms = 567;
    stats.apm_statistics.echo_return_loss = 890;
    stats.apm_statistics.echo_return_loss_enhancement = 1234;
    stats.apm_statistics.residual_echo_likelihood = 0.432f;
    stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
    stats.ana_statistics.bitrate_action_counter = 321;
    stats.ana_statistics.channel_action_counter = 432;
    stats.ana_statistics.dtx_action_counter = 543;
    stats.ana_statistics.fec_action_counter = 654;
    stats.ana_statistics.frame_length_increase_counter = 765;
    stats.ana_statistics.frame_length_decrease_counter = 876;
    stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
    stats.typing_noise_detected = true;
    return stats;
  }
  void SetAudioSendStreamStats() {
    for (auto* s : call_.GetAudioSendStreams()) {
      s->SetStats(GetAudioSendStreamStats());
    }
  }
  void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
                             bool is_sending) {
    const auto stats = GetAudioSendStreamStats();
    EXPECT_EQ(info.ssrc(), stats.local_ssrc);
    EXPECT_EQ(info.payload_bytes_sent, stats.payload_bytes_sent);
    EXPECT_EQ(info.header_and_padding_bytes_sent,
              stats.header_and_padding_bytes_sent);
    EXPECT_EQ(info.packets_sent, stats.packets_sent);
    EXPECT_EQ(info.packets_lost, stats.packets_lost);
    EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
    EXPECT_EQ(info.codec_name, stats.codec_name);
    EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
    EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
    EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
    EXPECT_EQ(info.audio_level, stats.audio_level);
    EXPECT_EQ(info.apm_statistics.delay_median_ms,
              stats.apm_statistics.delay_median_ms);
    EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
              stats.apm_statistics.delay_standard_deviation_ms);
    EXPECT_EQ(info.apm_statistics.echo_return_loss,
              stats.apm_statistics.echo_return_loss);
    EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
              stats.apm_statistics.echo_return_loss_enhancement);
    EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
              stats.apm_statistics.residual_echo_likelihood);
    EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
              stats.apm_statistics.residual_echo_likelihood_recent_max);
    EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
              stats.ana_statistics.bitrate_action_counter);
    EXPECT_EQ(info.ana_statistics.channel_action_counter,
              stats.ana_statistics.channel_action_counter);
    EXPECT_EQ(info.ana_statistics.dtx_action_counter,
              stats.ana_statistics.dtx_action_counter);
    EXPECT_EQ(info.ana_statistics.fec_action_counter,
              stats.ana_statistics.fec_action_counter);
    EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
              stats.ana_statistics.frame_length_increase_counter);
    EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
              stats.ana_statistics.frame_length_decrease_counter);
    EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
              stats.ana_statistics.uplink_packet_loss_fraction);
    EXPECT_EQ(info.typing_noise_detected,
              stats.typing_noise_detected && is_sending);
  }

  webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
    webrtc::AudioReceiveStream::Stats stats;
    stats.remote_ssrc = 123;
    stats.payload_bytes_rcvd = 456;
    stats.header_and_padding_bytes_rcvd = 67;
    stats.packets_rcvd = 768;
    stats.packets_lost = 101;
    stats.codec_name = "codec_name_recv";
    stats.codec_payload_type = 42;
    stats.jitter_ms = 901;
    stats.jitter_buffer_ms = 234;
    stats.jitter_buffer_preferred_ms = 567;
    stats.delay_estimate_ms = 890;
    stats.audio_level = 1234;
    stats.total_samples_received = 5678901;
    stats.concealed_samples = 234;
    stats.concealment_events = 12;
    stats.jitter_buffer_delay_seconds = 34;
    stats.jitter_buffer_emitted_count = 77;
    stats.expand_rate = 5.67f;
    stats.speech_expand_rate = 8.90f;
    stats.secondary_decoded_rate = 1.23f;
    stats.secondary_discarded_rate = 0.12f;
    stats.accelerate_rate = 4.56f;
    stats.preemptive_expand_rate = 7.89f;
    stats.decoding_calls_to_silence_generator = 12;
    stats.decoding_calls_to_neteq = 345;
    stats.decoding_normal = 67890;
    stats.decoding_plc = 1234;
    stats.decoding_codec_plc = 1236;
    stats.decoding_cng = 5678;
    stats.decoding_plc_cng = 9012;
    stats.decoding_muted_output = 3456;
    stats.capture_start_ntp_time_ms = 7890;
    return stats;
  }
  void SetAudioReceiveStreamStats() {
    for (auto* s : call_.GetAudioReceiveStreams()) {
      s->SetStats(GetAudioReceiveStreamStats());
    }
  }
  void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
    const auto stats = GetAudioReceiveStreamStats();
    EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
    EXPECT_EQ(info.payload_bytes_rcvd, stats.payload_bytes_rcvd);
    EXPECT_EQ(info.header_and_padding_bytes_rcvd,
              stats.header_and_padding_bytes_rcvd);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
              stats.packets_rcvd);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
              stats.packets_lost);
    EXPECT_EQ(info.codec_name, stats.codec_name);
    EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
              stats.jitter_buffer_ms);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
              stats.jitter_buffer_preferred_ms);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
              stats.delay_estimate_ms);
    EXPECT_EQ(info.audio_level, stats.audio_level);
    EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
    EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
    EXPECT_EQ(info.concealment_events, stats.concealment_events);
    EXPECT_EQ(info.jitter_buffer_delay_seconds,
              stats.jitter_buffer_delay_seconds);
    EXPECT_EQ(info.jitter_buffer_emitted_count,
              stats.jitter_buffer_emitted_count);
    EXPECT_EQ(info.expand_rate, stats.expand_rate);
    EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
    EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
    EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
    EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
    EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
    EXPECT_EQ(info.decoding_calls_to_silence_generator,
              stats.decoding_calls_to_silence_generator);
    EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
    EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
    EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
    EXPECT_EQ(info.decoding_codec_plc, stats.decoding_codec_plc);
    EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
    EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
    EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
    EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
  }
  void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
    EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
    for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
      ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
      EXPECT_EQ(info.send_codecs.find(codec.id)->second,
                codec.ToCodecParameters());
    }
    EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
    for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
      ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
      EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
                codec.ToCodecParameters());
    }
  }

  void VerifyGainControlEnabledCorrectly() {
    EXPECT_TRUE(apm_config_.gain_controller1.enabled);
    EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
    EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
    EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
  }

  void VerifyGainControlDefaultSettings() {
    EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
    EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
    EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
  }

  void VerifyEchoCancellationSettings(bool enabled) {
    constexpr bool kDefaultUseAecm =
#if defined(WEBRTC_ANDROID)
        true;
#else
        false;
#endif
    EXPECT_EQ(apm_config_.echo_canceller.enabled, enabled);
    EXPECT_EQ(apm_config_.echo_canceller.mobile_mode, kDefaultUseAecm);
  }

  bool IsHighPassFilterEnabled() {
    return apm_config_.high_pass_filter.enabled;
  }

  bool IsTypingDetectionEnabled() {
    return apm_config_.voice_detection.enabled;
  }

 protected:
  const bool use_null_apm_;
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
  rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm_;
  rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
  cricket::FakeCall call_;
  std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
  cricket::VoiceMediaChannel* channel_ = nullptr;
  cricket::AudioSendParameters send_parameters_;
  cricket::AudioRecvParameters recv_parameters_;
  FakeAudioSource fake_source_;
  webrtc::AudioProcessing::Config apm_config_;

 private:
  webrtc::test::ScopedFieldTrials override_field_trials_;
  webrtc::FieldTrialBasedConfig trials_config_;
};

INSTANTIATE_TEST_SUITE_P(TestBothWithAndWithoutNullApm,
                         WebRtcVoiceEngineTestFake,
                         ::testing::Values(false, true));

// Tests that we can create and destroy a channel.
TEST_P(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
  EXPECT_TRUE(SetupChannel());
}

// Test that we can add a send stream and that it has the correct defaults.
TEST_P(WebRtcVoiceEngineTestFake, CreateSendStream) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
  const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
  EXPECT_EQ(kSsrcX, config.rtp.ssrc);
  EXPECT_EQ("", config.rtp.c_name);
  EXPECT_EQ(0u, config.rtp.extensions.size());
  EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
            config.send_transport);
}

// Test that we can add a receive stream and that it has the correct defaults.
TEST_P(WebRtcVoiceEngineTestFake, CreateRecvStream) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  const webrtc::AudioReceiveStream::Config& config =
      GetRecvStreamConfig(kSsrcX);
  EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
  EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
  EXPECT_FALSE(config.rtp.transport_cc);
  EXPECT_EQ(0u, config.rtp.extensions.size());
  EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
            config.rtcp_send_transport);
  EXPECT_EQ("", config.sync_group);
}

TEST_P(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
  const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
  bool opus_found = false;
  for (const cricket::AudioCodec& codec : codecs) {
    if (codec.name == "opus") {
      EXPECT_TRUE(HasTransportCc(codec));
      opus_found = true;
    }
  }
  EXPECT_TRUE(opus_found);
}

// Test that we set our inbound codecs properly, including changing PT.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs[0].id = 106;  // collide with existing CN 32k
  parameters.codecs[2].id = 126;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}},
                   {106, {"ISAC", 16000, 1}},
                   {126, {"telephone-event", 8000, 1}},
                   {107, {"telephone-event", 32000, 1}}})));
}

// Test that we fail to set an unknown inbound codec.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

// Test that we fail if we have duplicate types in the inbound list.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[1].id = kIsacCodec.id;
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

// Test that we can decode OPUS without stereo parameters.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kOpusCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}},
                   {103, {"ISAC", 16000, 1}},
                   {111, {"opus", 48000, 2}}})));
}

// Test that we can decode OPUS with stereo = 0.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[2].params["stereo"] = "0";
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}},
                   {103, {"ISAC", 16000, 1}},
                   {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
}

// Test that we can decode OPUS with stereo = 1.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[2].params["stereo"] = "1";
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}},
                   {103, {"ISAC", 16000, 1}},
                   {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
}

// Test that changes to recv codecs are applied to all streams.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs[0].id = 106;  // collide with existing CN 32k
  parameters.codecs[2].id = 126;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  for (const auto& ssrc : {kSsrcX, kSsrcY}) {
    EXPECT_TRUE(AddRecvStream(ssrc));
    EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
                (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                    {{0, {"PCMU", 8000, 1}},
                     {106, {"ISAC", 16000, 1}},
                     {126, {"telephone-event", 8000, 1}},
                     {107, {"telephone-event", 32000, 1}}})));
  }
}

TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs[0].id = 106;  // collide with existing CN 32k
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
  ASSERT_EQ(1u, dm.count(106));
  EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
}

// Test that we can apply the same set of codecs again while playing.
TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  channel_->SetPlayout(true);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  // Remapping a payload type to a different codec should fail.
  parameters.codecs[0] = kOpusCodec;
  parameters.codecs[0].id = kIsacCodec.id;
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(GetRecvStream(kSsrcX).started());
}

// Test that we can add a codec while playing.
TEST_P(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  channel_->SetPlayout(true);

  parameters.codecs.push_back(kOpusCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(GetRecvStream(kSsrcX).started());
}

// Test that we accept adding the same codec with a different payload type.
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
TEST_P(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  ++parameters.codecs[0].id;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
}

// Test that we do allow setting Opus/Red by default.
TEST_P(WebRtcVoiceEngineTestFake, RecvRedDefault) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs[1].params[""] = "111/111";
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{111, {"opus", 48000, 2}},
                   {112, {"red", 48000, 2, {{"", "111/111"}}}}})));
}

// Test that we disable Opus/Red with the kill switch.
TEST_P(WebRtcVoiceEngineTestFake, RecvRed) {
  webrtc::test::ScopedFieldTrials override_field_trials(
      "WebRTC-Audio-Red-For-Opus/Disabled/");

  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs.push_back(kRed48000Codec);
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

TEST_P(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
  EXPECT_TRUE(SetupSendStream());

  // Test that when autobw is enabled, bitrate is kept as the default
  // value. autobw is enabled for the following tests because the target
  // bitrate is <= 0.

  // ISAC, default bitrate == 32000.
  TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);

  // PCMU, default bitrate == 64000.
  TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);

  // opus, default bitrate == 32000 in mono.
  TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
}

TEST_P(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
  EXPECT_TRUE(SetupSendStream());

  // ISAC, default bitrate == 32000.
  TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
  // Rates above the max (56000) should be capped.
  TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);

  // opus, default bitrate == 64000.
  TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
  TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
  // Rates above the max (510000) should be capped.
  TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
}

TEST_P(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
  EXPECT_TRUE(SetupSendStream());

  // Test that we can only set a maximum bitrate for a fixed-rate codec
  // if it's bigger than the fixed rate.

  // PCMU, fixed bitrate == 64000.
  TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
  TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
}

TEST_P(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
  EXPECT_TRUE(SetupChannel());
  const int kDesiredBitrate = 128000;
  cricket::AudioSendParameters parameters;
  parameters.codecs = engine_->send_codecs();
  parameters.max_bandwidth_bps = kDesiredBitrate;
  SetSendParameters(parameters);

  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));

  EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
}

// Test that bitrate cannot be set for CBR codecs.
// Bitrate is ignored if it is higher than the fixed bitrate.
// Bitrate less then the fixed bitrate is an error.
TEST_P(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
  EXPECT_TRUE(SetupSendStream());

  // PCMU, default bitrate == 64000.
  SetSendParameters(send_parameters_);
  EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));

  send_parameters_.max_bandwidth_bps = 128000;
  SetSendParameters(send_parameters_);
  EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));

  send_parameters_.max_bandwidth_bps = 128;
  EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
  EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
}

// Test that the per-stream bitrate limit and the global
// bitrate limit both apply.
TEST_P(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
  EXPECT_TRUE(SetupSendStream());

  // opus, default bitrate == 32000.
  SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
  SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
  SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
  SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);

  // CBR codecs allow both maximums to exceed the bitrate.
  SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
  SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
  SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
  SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);

  // CBR codecs don't allow per stream maximums to be too low.
  SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
  SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
}

// Test that an attempt to set RtpParameters for a stream that does not exist
// fails.
TEST_P(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
  EXPECT_TRUE(SetupChannel());
  webrtc::RtpParameters nonexistent_parameters =
      channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(0u, nonexistent_parameters.encodings.size());

  nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(
      channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
}

TEST_P(WebRtcVoiceEngineTestFake,
       CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
  // This test verifies that setting RtpParameters succeeds only if
  // the structure contains exactly one encoding.
  // TODO(skvlad): Update this test when we start supporting setting parameters
  // for each encoding individually.

  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  // Two or more encodings should result in failure.
  parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  // Zero encodings should also fail.
  parameters.encodings.clear();
  EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
}

// Changing the SSRC through RtpParameters is not allowed.
TEST_P(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  parameters.encodings[0].ssrc = 0xdeadbeef;
  EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
}

// Test that a stream will not be sending if its encoding is made
// inactive through SetRtpSendParameters.
TEST_P(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
  EXPECT_TRUE(SetupSendStream());
  SetSend(true);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
  // Get current parameters and change "active" to false.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_TRUE(parameters.encodings[0].active);
  parameters.encodings[0].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());

  // Now change it back to active and verify we resume sending.
  // This should occur even when other parameters are updated.
  parameters.encodings[0].active = true;
  parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
}

TEST_P(WebRtcVoiceEngineTestFake, SetRtpParametersAdaptivePtime) {
  EXPECT_TRUE(SetupSendStream());
  // Get current parameters and change "adaptive_ptime" to true.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_FALSE(parameters.encodings[0].adaptive_ptime);
  parameters.encodings[0].adaptive_ptime = true;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_TRUE(GetAudioNetworkAdaptorConfig(kSsrcX));
  EXPECT_EQ(16000, GetSendStreamConfig(kSsrcX).min_bitrate_bps);

  parameters.encodings[0].adaptive_ptime = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_FALSE(GetAudioNetworkAdaptorConfig(kSsrcX));
  EXPECT_EQ(32000, GetSendStreamConfig(kSsrcX).min_bitrate_bps);
}

TEST_P(WebRtcVoiceEngineTestFake,
       DisablingAdaptivePtimeDoesNotRemoveAudioNetworkAdaptorFromOptions) {
  EXPECT_TRUE(SetupSendStream());
  send_parameters_.options.audio_network_adaptor = true;
  send_parameters_.options.audio_network_adaptor_config = {"1234"};
  SetSendParameters(send_parameters_);
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  parameters.encodings[0].adaptive_ptime = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
}

TEST_P(WebRtcVoiceEngineTestFake, AdaptivePtimeFieldTrial) {
  webrtc::test::ScopedFieldTrials override_field_trials(
      "WebRTC-Audio-AdaptivePtime/enabled:true/");
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(GetAudioNetworkAdaptorConfig(kSsrcX));
}

// Test that SetRtpSendParameters configures the correct encoding channel for
// each SSRC.
TEST_P(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
  SetupForMultiSendStream();
  // Create send streams.
  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
  }
  // Configure one stream to be limited by the stream config, another to be
  // limited by the global max, and the third one with no per-stream limit
  // (still subject to the global limit).
  SetGlobalMaxBitrate(kOpusCodec, 32000);
  EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
  EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
  EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));

  EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
  EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
  EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));

  // Remove the global cap; the streams should switch to their respective
  // maximums (or remain unchanged if there was no other limit on them.)
  SetGlobalMaxBitrate(kOpusCodec, -1);
  EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
  EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
  EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
}

// Test that GetRtpSendParameters returns the currently configured codecs.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  SetSendParameters(parameters);

  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
  EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
}

// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
  cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
  params.cname = "rtcpcname";
  EXPECT_TRUE(SetupSendStream(params));

  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
}

TEST_P(WebRtcVoiceEngineTestFake,
       DetectRtpSendParameterHeaderExtensionsChange) {
  EXPECT_TRUE(SetupSendStream());

  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  rtp_parameters.header_extensions.emplace_back();

  EXPECT_NE(0u, rtp_parameters.header_extensions.size());

  webrtc::RTCError result =
      channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
  EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
}

// Test that GetRtpSendParameters returns an SSRC.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
}

// Test that if we set/get parameters multiple times, we get the same results.
TEST_P(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  SetSendParameters(parameters);

  webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);

  // We should be able to set the params we just got.
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());

  // ... And this shouldn't change the params returned by GetRtpSendParameters.
  webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
}

// Test that max_bitrate_bps in send stream config gets updated correctly when
// SetRtpSendParameters is called.
TEST_P(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters send_parameters;
  send_parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(send_parameters);

  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  // Expect empty on parameters.encodings[0].max_bitrate_bps;
  EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);

  constexpr int kMaxBitrateBps = 6000;
  rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());

  const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
  EXPECT_EQ(max_bitrate, kMaxBitrateBps);
}

// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
// a value <= 0, setting the parameters returns false.
TEST_P(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(1UL, rtp_parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            rtp_parameters.encodings[0].bitrate_priority);

  rtp_parameters.encodings[0].bitrate_priority = 0;
  EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
  rtp_parameters.encodings[0].bitrate_priority = -1.0;
  EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
}

// Test that the bitrate_priority in the send stream config gets updated when
// SetRtpSendParameters is set for the VoiceMediaChannel.
TEST_P(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);

  EXPECT_EQ(1UL, rtp_parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            rtp_parameters.encodings[0].bitrate_priority);
  double new_bitrate_priority = 2.0;
  rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
  EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());

  // The priority should get set for both the audio channel's rtp parameters
  // and the audio send stream's audio config.
  EXPECT_EQ(
      new_bitrate_priority,
      channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
  EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
}

// Test that GetRtpReceiveParameters returns the currently configured codecs.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpReceiveParameters(kSsrcX);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
  EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
}

// Test that GetRtpReceiveParameters returns an SSRC.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
  EXPECT_TRUE(SetupRecvStream());
  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpReceiveParameters(kSsrcX);
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
}

// Test that if we set/get parameters multiple times, we get the same results.
TEST_P(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  webrtc::RtpParameters initial_params =
      channel_->GetRtpReceiveParameters(kSsrcX);

  // ... And this shouldn't change the params returned by
  // GetRtpReceiveParameters.
  webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
  EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
}

// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
// aren't signaled. It should return an empty "RtpEncodingParameters" when
// configured to receive an unsignaled stream and no packets have been received
// yet, and start returning the SSRC once a packet has been received.
TEST_P(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
  ASSERT_TRUE(SetupChannel());
  // Call necessary methods to configure receiving a default stream as
  // soon as it arrives.
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  // Call GetDefaultRtpReceiveParameters before configured to receive an
  // unsignaled stream. Should return nothing.
  EXPECT_EQ(webrtc::RtpParameters(),
            channel_->GetDefaultRtpReceiveParameters());

  // Set a sink for an unsignaled stream.
  std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
  channel_->SetDefaultRawAudioSink(std::move(fake_sink));

  // Call GetDefaultRtpReceiveParameters before the SSRC is known.
  webrtc::RtpParameters rtp_parameters =
      channel_->GetDefaultRtpReceiveParameters();
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);

  // Receive PCMU packet (SSRC=1).
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

  // The `ssrc` member should still be unset.
  rtp_parameters = channel_->GetDefaultRtpReceiveParameters();
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
}

// Test that we apply codecs properly.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecs) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs[0].id = 96;
  parameters.codecs[0].bitrate = 22000;
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, send_codec_spec.payload_type);
  EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
  EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
  EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
  EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
  EXPECT_FALSE(channel_->CanInsertDtmf());
}

// Test that we use Opus/Red by default when it is
// listed as the first codec and there is an fmtp line.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsRed) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs[0].params[""] = "111/111";
  parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
  EXPECT_EQ(112, send_codec_spec.red_payload_type);
}

// Test that we do not use Opus/Red by default when it is
// listed as the first codec but there is no fmtp line.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsRedNoFmtp) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
}

// Test that we do not use Opus/Red by default.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsRedDefault) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs[1].params[""] = "111/111";
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
}

// Test that the RED fmtp line must match the payload type.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsRedFmtpMismatch) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs[0].params[""] = "8/8";
  parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
}

// Test that the RED fmtp line must show 2..32 payloads.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsRedFmtpAmountOfRedundancy) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kRed48000Codec);
  parameters.codecs[0].params[""] = "111";
  parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
  for (int i = 1; i < 32; i++) {
    parameters.codecs[0].params[""] += "/111";
    SetSendParameters(parameters);
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(111, send_codec_spec.payload_type);
    EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
    EXPECT_EQ(112, send_codec_spec.red_payload_type);
  }
  parameters.codecs[0].params[""] += "/111";
  SetSendParameters(parameters);
  const auto& send_codec_spec2 = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec2.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec2.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec2.red_payload_type);
}

// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
// AudioSendStream.
TEST_P(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs[0].id = 96;
  parameters.codecs[0].bitrate = 48000;
  const int initial_num = call_.GetNumCreatedSendStreams();
  SetSendParameters(parameters);
  EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
  // Calling SetSendCodec again with same codec which is already set.
  // In this case media channel shouldn't send codec to VoE.
  SetSendParameters(parameters);
  EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
}

// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
// tests should be available in AudioEncoderOpusTest.

// Test that if clockrate is not 48000 for opus, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].clockrate = 50000;
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that if channels=0 for opus, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].channels = 0;
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that if channels=0 for opus, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].channels = 0;
  parameters.codecs[0].params["stereo"] = "1";
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that if channel is 1 for opus and there's no stereo, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].channels = 1;
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that if channel is 1 for opus and stereo=0, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].channels = 1;
  parameters.codecs[0].params["stereo"] = "0";
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that if channel is 1 for opus and stereo=1, we fail.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].channels = 1;
  parameters.codecs[0].params["stereo"] = "1";
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that with bitrate=0 and no stereo, bitrate is 32000.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 32000);
}

// Test that with bitrate=0 and stereo=0, bitrate is 32000.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].params["stereo"] = "0";
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 32000);
}

// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].params["stereo"] = "0";
  // bitrate that's out of the range between 6000 and 510000 will be clamped.
  parameters.codecs[0].bitrate = 5999;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 6000);

  parameters.codecs[0].bitrate = 510001;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 510000);
}

// Test that with bitrate=0 and stereo=1, bitrate is 64000.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 0;
  parameters.codecs[0].params["stereo"] = "1";
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 64000);
}

// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].params["stereo"] = "1";
  // bitrate that's out of the range between 6000 and 510000 will be clamped.
  parameters.codecs[0].bitrate = 5999;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 6000);

  parameters.codecs[0].bitrate = 510001;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 510000);
}

// Test that with bitrate=N and stereo unset, bitrate is N.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 96000;
  SetSendParameters(parameters);
  const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, spec.payload_type);
  EXPECT_EQ(96000, spec.target_bitrate_bps);
  EXPECT_EQ("opus", spec.format.name);
  EXPECT_EQ(2u, spec.format.num_channels);
  EXPECT_EQ(48000, spec.format.clockrate_hz);
}

// Test that with bitrate=N and stereo=0, bitrate is N.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 30000;
  parameters.codecs[0].params["stereo"] = "0";
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 30000);
}

// Test that with bitrate=N and without any parameters, bitrate is N.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 30000;
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 30000);
}

// Test that with bitrate=N and stereo=1, bitrate is N.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].bitrate = 30000;
  parameters.codecs[0].params["stereo"] = "1";
  SetSendParameters(parameters);
  CheckSendCodecBitrate(kSsrcX, "opus", 30000);
}

TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
  SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
                                     200000);
}

TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
  SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
}

TEST_P(WebRtcVoiceEngineTestFake,
       SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
  SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
}

TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
  SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
}

TEST_P(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
  SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
                                     200000);
  send_parameters_.max_bandwidth_bps = 100000;
  // Setting max bitrate should keep previous min bitrate
  // Setting max bitrate should not reset start bitrate.
  EXPECT_CALL(*call_.GetMockTransportControllerSend(),
              SetSdpBitrateParameters(
                  AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
                        Field(&BitrateConstraints::start_bitrate_bps, -1),
                        Field(&BitrateConstraints::max_bitrate_bps, 200000))));
  SetSendParameters(send_parameters_);
}

// Test that we can enable NACK with opus as callee.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
  SetSendParameters(parameters);
  // NACK should be enabled even with no send stream.
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);

  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
}

// Test that we can enable NACK on receive streams.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
  SetSendParameters(parameters);
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
}

// Test that we can disable NACK on receive streams.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  SetSendParameters(parameters);
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);

  parameters.codecs.clear();
  parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(parameters);
  EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
}

// Test that NACK is enabled on a new receive stream.
TEST_P(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  SetSendParameters(parameters);

  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
  EXPECT_TRUE(AddRecvStream(kSsrcZ));
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
}

TEST_P(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioSendParameters send_parameters;
  send_parameters.codecs.push_back(kOpusCodec);
  EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
  SetSendParameters(send_parameters);

  cricket::AudioRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(kIsacCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
  EXPECT_FALSE(
      call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);

  send_parameters.codecs = engine_->send_codecs();
  SetSendParameters(send_parameters);
  ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
  EXPECT_TRUE(
      call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
}

// Test that we can switch back and forth between Opus and ISAC with CN.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
  EXPECT_TRUE(SetupSendStream());

  cricket::AudioSendParameters opus_parameters;
  opus_parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(opus_parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(111, spec.payload_type);
    EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
  }

  cricket::AudioSendParameters isac_parameters;
  isac_parameters.codecs.push_back(kIsacCodec);
  isac_parameters.codecs.push_back(kCn16000Codec);
  isac_parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(isac_parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(103, spec.payload_type);
    EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
  }

  SetSendParameters(opus_parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(111, spec.payload_type);
    EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
  }
}

// Test that we handle various ways of specifying bitrate.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);  // bitrate == 32000
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(103, spec.payload_type);
    EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
    EXPECT_EQ(32000, spec.target_bitrate_bps);
  }

  parameters.codecs[0].bitrate = 0;  // bitrate == default
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(103, spec.payload_type);
    EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
    EXPECT_EQ(32000, spec.target_bitrate_bps);
  }
  parameters.codecs[0].bitrate = 28000;  // bitrate == 28000
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(103, spec.payload_type);
    EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
    EXPECT_EQ(28000, spec.target_bitrate_bps);
  }

  parameters.codecs[0] = kPcmuCodec;  // bitrate == 64000
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(0, spec.payload_type);
    EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
    EXPECT_EQ(64000, spec.target_bitrate_bps);
  }

  parameters.codecs[0].bitrate = 0;  // bitrate == default
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(0, spec.payload_type);
    EXPECT_STREQ("PCMU", spec.format.name.c_str());
    EXPECT_EQ(64000, spec.target_bitrate_bps);
  }

  parameters.codecs[0] = kOpusCodec;
  parameters.codecs[0].bitrate = 0;  // bitrate == default
  SetSendParameters(parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(111, spec.payload_type);
    EXPECT_STREQ("opus", spec.format.name.c_str());
    EXPECT_EQ(32000, spec.target_bitrate_bps);
  }
}

// Test that we fail if no codecs are specified.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
}

// Test that we can set send codecs even with telephone-event codec as the first
// one on the list.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs[0].id = 98;  // DTMF
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
}

// Test that CanInsertDtmf() is governed by the send flag
TEST_P(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs[0].id = 98;  // DTMF
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  EXPECT_FALSE(channel_->CanInsertDtmf());
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
  SetSend(false);
  EXPECT_FALSE(channel_->CanInsertDtmf());
}

// Test that payload type range is limited for telephone-event codec.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs[0].id = 0;  // DTMF
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = 128;  // DTMF
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
  EXPECT_FALSE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = 127;
  SetSendParameters(parameters);
  EXPECT_TRUE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = -1;  // DTMF
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
  EXPECT_FALSE(channel_->CanInsertDtmf());
}

// Test that we can set send codecs even with CN codec as the first
// one on the list.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs[0].id = 98;  // wideband CN
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
  EXPECT_EQ(98, send_codec_spec.cng_payload_type);
}

// Test that we set VAD and DTMF types correctly as caller.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  // TODO(juberti): cn 32000
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs[0].id = 96;
  parameters.codecs[2].id = 97;  // wideband CN
  parameters.codecs[4].id = 98;  // DTMF
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
  EXPECT_EQ(1u, send_codec_spec.format.num_channels);
  EXPECT_EQ(97, send_codec_spec.cng_payload_type);
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
}

// Test that we set VAD and DTMF types correctly as callee.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  // TODO(juberti): cn 32000
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs[0].id = 96;
  parameters.codecs[2].id = 97;  // wideband CN
  parameters.codecs[4].id = 98;  // DTMF
  SetSendParameters(parameters);
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));

  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
  EXPECT_EQ(1u, send_codec_spec.format.num_channels);
  EXPECT_EQ(97, send_codec_spec.cng_payload_type);
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
}

// Test that we only apply VAD if we have a CN codec that matches the
// send codec clockrate.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  // Set ISAC(16K) and CN(16K). VAD should be activated.
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[1].id = 97;
  SetSendParameters(parameters);
  {
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
    EXPECT_EQ(1u, send_codec_spec.format.num_channels);
    EXPECT_EQ(97, send_codec_spec.cng_payload_type);
  }
  // Set PCMU(8K) and CN(16K). VAD should not be activated.
  parameters.codecs[0] = kPcmuCodec;
  SetSendParameters(parameters);
  {
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
  }
  // Set PCMU(8K) and CN(8K). VAD should be activated.
  parameters.codecs[1] = kCn8000Codec;
  SetSendParameters(parameters);
  {
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
    EXPECT_EQ(1u, send_codec_spec.format.num_channels);
    EXPECT_EQ(13, send_codec_spec.cng_payload_type);
  }
  // Set ISAC(16K) and CN(8K). VAD should not be activated.
  parameters.codecs[0] = kIsacCodec;
  SetSendParameters(parameters);
  {
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
  }
}

// Test that we perform case-insensitive matching of codec names.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs[0].name = "iSaC";
  parameters.codecs[0].id = 96;
  parameters.codecs[2].id = 97;  // wideband CN
  parameters.codecs[4].id = 98;  // DTMF
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
  EXPECT_EQ(1u, send_codec_spec.format.num_channels);
  EXPECT_EQ(97, send_codec_spec.cng_payload_type);
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
}

TEST_P(WebRtcVoiceEngineTestFake,
       SupportsTransportSequenceNumberHeaderExtension) {
  const std::vector<webrtc::RtpExtension> header_extensions =
      GetDefaultEnabledRtpHeaderExtensions(*engine_);
  EXPECT_THAT(header_extensions,
              Contains(::testing::Field(
                  "uri", &RtpExtension::uri,
                  webrtc::RtpExtension::kTransportSequenceNumberUri)));
}

// Test support for audio level header extension.
TEST_P(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
}
TEST_P(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
}

// Test support for transport sequence number header extension.
TEST_P(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(
      webrtc::RtpExtension::kTransportSequenceNumberUri);
}
TEST_P(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(
      webrtc::RtpExtension::kTransportSequenceNumberUri);
}

// Test that we can create a channel and start sending on it.
TEST_P(WebRtcVoiceEngineTestFake, Send) {
  EXPECT_TRUE(SetupSendStream());
  SetSendParameters(send_parameters_);
  SetSend(true);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
  SetSend(false);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
}

// Test that a channel will send if and only if it has a source and is enabled
// for sending.
TEST_P(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
  EXPECT_TRUE(SetupSendStream());
  SetSendParameters(send_parameters_);
  SetAudioSend(kSsrcX, true, nullptr);
  SetSend(true);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
  SetAudioSend(kSsrcX, true, &fake_source_);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
  SetAudioSend(kSsrcX, true, nullptr);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
}

// Test that a channel is muted/unmuted.
TEST_P(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
  EXPECT_TRUE(SetupSendStream());
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(GetSendStream(kSsrcX).muted());
  SetAudioSend(kSsrcX, true, nullptr);
  EXPECT_FALSE(GetSendStream(kSsrcX).muted());
  SetAudioSend(kSsrcX, false, nullptr);
  EXPECT_TRUE(GetSendStream(kSsrcX).muted());
}

// Test that SetSendParameters() does not alter a stream's send state.
TEST_P(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());

  // Turn on sending.
  SetSend(true);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());

  // Changing RTP header extensions will recreate the AudioSendStream.
  send_parameters_.extensions.push_back(
      webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());

  // Turn off sending.
  SetSend(false);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());

  // Changing RTP header extensions will recreate the AudioSendStream.
  send_parameters_.extensions.clear();
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
}

// Test that we can create a channel and start playing out on it.
TEST_P(WebRtcVoiceEngineTestFake, Playout) {
  EXPECT_TRUE(SetupRecvStream());
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
  channel_->SetPlayout(true);
  EXPECT_TRUE(GetRecvStream(kSsrcX).started());
  channel_->SetPlayout(false);
  EXPECT_FALSE(GetRecvStream(kSsrcX).started());
}

// Test that we can add and remove send streams.
TEST_P(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
  SetupForMultiSendStream();

  // Set the global state for sending.
  SetSend(true);

  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
    SetAudioSend(ssrc, true, &fake_source_);
    // Verify that we are in a sending state for all the created streams.
    EXPECT_TRUE(GetSendStream(ssrc).IsSending());
  }
  EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());

  // Delete the send streams.
  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
    EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
    EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
  }
  EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
}

// Test SetSendCodecs correctly configure the codecs in all send streams.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
  SetupForMultiSendStream();

  // Create send streams.
  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
  }

  cricket::AudioSendParameters parameters;
  // Set ISAC(16K) and CN(16K). VAD should be activated.
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[1].id = 97;
  SetSendParameters(parameters);

  // Verify ISAC and VAD are corrected configured on all send channels.
  for (uint32_t ssrc : kSsrcs4) {
    ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
    const auto& send_codec_spec =
        *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
    EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
    EXPECT_EQ(1u, send_codec_spec.format.num_channels);
    EXPECT_EQ(97, send_codec_spec.cng_payload_type);
  }

  // Change to PCMU(8K) and CN(16K).
  parameters.codecs[0] = kPcmuCodec;
  SetSendParameters(parameters);
  for (uint32_t ssrc : kSsrcs4) {
    ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
    const auto& send_codec_spec =
        *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
    EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
  }
}

// Test we can SetSend on all send streams correctly.
TEST_P(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
  SetupForMultiSendStream();

  // Create the send channels and they should be a "not sending" date.
  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
    SetAudioSend(ssrc, true, &fake_source_);
    EXPECT_FALSE(GetSendStream(ssrc).IsSending());
  }

  // Set the global state for starting sending.
  SetSend(true);
  for (uint32_t ssrc : kSsrcs4) {
    // Verify that we are in a sending state for all the send streams.
    EXPECT_TRUE(GetSendStream(ssrc).IsSending());
  }

  // Set the global state for stopping sending.
  SetSend(false);
  for (uint32_t ssrc : kSsrcs4) {
    // Verify that we are in a stop state for all the send streams.
    EXPECT_FALSE(GetSendStream(ssrc).IsSending());
  }
}

// Test we can set the correct statistics on all send streams.
TEST_P(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
  SetupForMultiSendStream();

  // Create send streams.
  for (uint32_t ssrc : kSsrcs4) {
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
  }

  // Create a receive stream to check that none of the send streams end up in
  // the receive stream stats.
  EXPECT_TRUE(AddRecvStream(kSsrcY));

  // We need send codec to be set to get all stats.
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
  SetAudioSendStreamStats();

  // Check stats for the added streams.
  {
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    cricket::VoiceMediaInfo info;
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));

    // We have added 4 send streams. We should see empty stats for all.
    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
    for (const auto& sender : info.senders) {
      VerifyVoiceSenderInfo(sender, false);
    }
    VerifyVoiceSendRecvCodecs(info);

    // We have added one receive stream. We should see empty stats.
    EXPECT_EQ(info.receivers.size(), 1u);
    EXPECT_EQ(info.receivers[0].ssrc(), 0u);
  }

  // Remove the kSsrcY stream. No receiver stats.
  {
    cricket::VoiceMediaInfo info;
    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
    EXPECT_EQ(0u, info.receivers.size());
  }

  // Deliver a new packet - a default receive stream should be created and we
  // should see stats again.
  {
    cricket::VoiceMediaInfo info;
    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
    SetAudioReceiveStreamStats();
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
    EXPECT_EQ(1u, info.receivers.size());
    VerifyVoiceReceiverInfo(info.receivers[0]);
    VerifyVoiceSendRecvCodecs(info);
  }
}

// Test that we can add and remove receive streams, and do proper send/playout.
// We can receive on multiple streams while sending one stream.
TEST_P(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
  EXPECT_TRUE(SetupSendStream());

  // Start playout without a receive stream.
  SetSendParameters(send_parameters_);
  channel_->SetPlayout(true);

  // Adding another stream should enable playout on the new stream only.
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  SetSend(true);
  EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());

  // Make sure only the new stream is played out.
  EXPECT_TRUE(GetRecvStream(kSsrcY).started());

  // Adding yet another stream should have stream 2 and 3 enabled for playout.
  EXPECT_TRUE(AddRecvStream(kSsrcZ));
  EXPECT_TRUE(GetRecvStream(kSsrcY).started());
  EXPECT_TRUE(GetRecvStream(kSsrcZ).started());

  // Stop sending.
  SetSend(false);
  EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());

  // Stop playout.
  channel_->SetPlayout(false);
  EXPECT_FALSE(GetRecvStream(kSsrcY).started());
  EXPECT_FALSE(GetRecvStream(kSsrcZ).started());

  // Restart playout and make sure recv streams are played out.
  channel_->SetPlayout(true);
  EXPECT_TRUE(GetRecvStream(kSsrcY).started());
  EXPECT_TRUE(GetRecvStream(kSsrcZ).started());

  // Now remove the recv streams.
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
}

TEST_P(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_CALL(*adm_, BuiltInAGCIsAvailable())
      .Times(::testing::AtLeast(1))
      .WillRepeatedly(Return(false));

  if (!use_null_apm_) {
    // Ensure default options.
    VerifyGainControlEnabledCorrectly();
    VerifyGainControlDefaultSettings();
  }

  const auto& agc_config = apm_config_.gain_controller1;

  send_parameters_.options.auto_gain_control = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_FALSE(agc_config.enabled);
  }
  send_parameters_.options.auto_gain_control = absl::nullopt;

  send_parameters_.options.tx_agc_target_dbov = 5;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_EQ(5, agc_config.target_level_dbfs);
  }
  send_parameters_.options.tx_agc_target_dbov = absl::nullopt;

  send_parameters_.options.tx_agc_digital_compression_gain = 10;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_EQ(10, agc_config.compression_gain_db);
  }
  send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;

  send_parameters_.options.tx_agc_limiter = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_FALSE(agc_config.enable_limiter);
  }
  send_parameters_.options.tx_agc_limiter = absl::nullopt;

  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    // Expect all options to have been preserved.
    EXPECT_FALSE(agc_config.enabled);
    EXPECT_EQ(5, agc_config.target_level_dbfs);
    EXPECT_EQ(10, agc_config.compression_gain_db);
    EXPECT_FALSE(agc_config.enable_limiter);
  }
}

TEST_P(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
  EXPECT_TRUE(SetupSendStream());
  send_parameters_.options.audio_network_adaptor = true;
  send_parameters_.options.audio_network_adaptor_config = {"1234"};
  SetSendParameters(send_parameters_);
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
}

TEST_P(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
  EXPECT_TRUE(SetupSendStream());
  send_parameters_.options.audio_network_adaptor = true;
  send_parameters_.options.audio_network_adaptor_config = {"1234"};
  SetSendParameters(send_parameters_);
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
  cricket::AudioOptions options;
  options.audio_network_adaptor = false;
  SetAudioSend(kSsrcX, true, nullptr, &options);
  EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
}

TEST_P(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
  EXPECT_TRUE(SetupSendStream());
  send_parameters_.options.audio_network_adaptor = true;
  send_parameters_.options.audio_network_adaptor_config = {"1234"};
  SetSendParameters(send_parameters_);
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
  const int initial_num = call_.GetNumCreatedSendStreams();
  cricket::AudioOptions options;
  options.audio_network_adaptor = absl::nullopt;
  // Unvalued `options.audio_network_adaptor` should not reset audio network
  // adaptor.
  SetAudioSend(kSsrcX, true, nullptr, &options);
  // AudioSendStream not expected to be recreated.
  EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
}

class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
    : public WebRtcVoiceEngineTestFake {
 public:
  WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
      : WebRtcVoiceEngineTestFake(
            "WebRTC-Audio-Allocation/min:6000bps,max:32000bps/") {}
};

// Test that we can set the outgoing SSRC properly.
// SSRC is set in SetupSendStream() by calling AddSendStream.
TEST_P(WebRtcVoiceEngineTestFake, SetSendSsrc) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
}

TEST_P(WebRtcVoiceEngineTestFake, GetStats) {
  // Setup. We need send codec to be set to get all stats.
  EXPECT_TRUE(SetupSendStream());
  // SetupSendStream adds a send stream with kSsrcX, so the receive
  // stream has to use a different SSRC.
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
  SetAudioSendStreamStats();

  // Check stats for the added streams.
  {
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    cricket::VoiceMediaInfo info;
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));

    // We have added one send stream. We should see the stats we've set.
    EXPECT_EQ(1u, info.senders.size());
    VerifyVoiceSenderInfo(info.senders[0], false);
    // We have added one receive stream. We should see empty stats.
    EXPECT_EQ(info.receivers.size(), 1u);
    EXPECT_EQ(info.receivers[0].ssrc(), 0u);
  }

  // Start sending - this affects some reported stats.
  {
    cricket::VoiceMediaInfo info;
    SetSend(true);
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));
    VerifyVoiceSenderInfo(info.senders[0], true);
    VerifyVoiceSendRecvCodecs(info);
  }

  // Remove the kSsrcY stream. No receiver stats.
  {
    cricket::VoiceMediaInfo info;
    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(1u, info.senders.size());
    EXPECT_EQ(0u, info.receivers.size());
  }

  // Deliver a new packet - a default receive stream should be created and we
  // should see stats again.
  {
    cricket::VoiceMediaInfo info;
    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
    SetAudioReceiveStreamStats();
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true,
              channel_->GetStats(&info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(1u, info.senders.size());
    EXPECT_EQ(1u, info.receivers.size());
    VerifyVoiceReceiverInfo(info.receivers[0]);
    VerifyVoiceSendRecvCodecs(info);
  }
}

// Test that we can set the outgoing SSRC properly with multiple streams.
// SSRC is set in SetupSendStream() by calling AddSendStream.
TEST_P(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
}

// Test that the local SSRC is the same on sending and receiving channels if the
// receive channel is created before the send channel.
TEST_P(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
  EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
}

// Test that we can properly receive packets.
TEST_P(WebRtcVoiceEngineTestFake, Recv) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(AddRecvStream(1));
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

  EXPECT_TRUE(
      GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
}

// Test that we can properly receive packets on multiple streams.
TEST_P(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
  EXPECT_TRUE(SetupChannel());
  const uint32_t ssrc1 = 1;
  const uint32_t ssrc2 = 2;
  const uint32_t ssrc3 = 3;
  EXPECT_TRUE(AddRecvStream(ssrc1));
  EXPECT_TRUE(AddRecvStream(ssrc2));
  EXPECT_TRUE(AddRecvStream(ssrc3));
  // Create packets with the right SSRCs.
  unsigned char packets[4][sizeof(kPcmuFrame)];
  for (size_t i = 0; i < arraysize(packets); ++i) {
    memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
    rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
  }

  const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
  const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
  const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);

  EXPECT_EQ(s1.received_packets(), 0);
  EXPECT_EQ(s2.received_packets(), 0);
  EXPECT_EQ(s3.received_packets(), 0);

  DeliverPacket(packets[0], sizeof(packets[0]));
  EXPECT_EQ(s1.received_packets(), 0);
  EXPECT_EQ(s2.received_packets(), 0);
  EXPECT_EQ(s3.received_packets(), 0);

  DeliverPacket(packets[1], sizeof(packets[1]));
  EXPECT_EQ(s1.received_packets(), 1);
  EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
  EXPECT_EQ(s2.received_packets(), 0);
  EXPECT_EQ(s3.received_packets(), 0);

  DeliverPacket(packets[2], sizeof(packets[2]));
  EXPECT_EQ(s1.received_packets(), 1);
  EXPECT_EQ(s2.received_packets(), 1);
  EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
  EXPECT_EQ(s3.received_packets(), 0);

  DeliverPacket(packets[3], sizeof(packets[3]));
  EXPECT_EQ(s1.received_packets(), 1);
  EXPECT_EQ(s2.received_packets(), 1);
  EXPECT_EQ(s3.received_packets(), 1);
  EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));

  EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
  EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
  EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
}

// Test that receiving on an unsignaled stream works (a stream is created).
TEST_P(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());

  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  EXPECT_TRUE(
      GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
}

// Tests that when we add a stream without SSRCs, but contains a stream_id
// that it is stored and its stream id is later used when the first packet
// arrives to properly create a receive stream with a sync label.
TEST_P(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
  const char kSyncLabel[] = "sync_label";
  EXPECT_TRUE(SetupChannel());
  cricket::StreamParams unsignaled_stream;
  unsignaled_stream.set_stream_ids({kSyncLabel});
  ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
  // The stream shouldn't have been created at this point because it doesn't
  // have any SSRCs.
  EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());

  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  EXPECT_TRUE(
      GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
  EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);

  // Remset the unsignaled stream to clear the cached parameters. If a new
  // default unsignaled receive stream is created it will not have a sync group.
  channel_->ResetUnsignaledRecvStream();
  channel_->RemoveRecvStream(kSsrc1);

  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  EXPECT_TRUE(
      GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
  EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
}

TEST_P(WebRtcVoiceEngineTestFake,
       ResetUnsignaledRecvStreamDeletesAllDefaultStreams) {
  ASSERT_TRUE(SetupChannel());
  // No receive streams to start with.
  ASSERT_TRUE(call_.GetAudioReceiveStreams().empty());

  // Deliver a couple packets with unsignaled SSRCs.
  unsigned char packet[sizeof(kPcmuFrame)];
  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
  rtc::SetBE32(&packet[8], 0x1234);
  DeliverPacket(packet, sizeof(packet));
  rtc::SetBE32(&packet[8], 0x5678);
  DeliverPacket(packet, sizeof(packet));

  // Verify that the receive streams were created.
  const auto& receivers1 = call_.GetAudioReceiveStreams();
  ASSERT_EQ(receivers1.size(), 2u);

  // Should remove all default streams.
  channel_->ResetUnsignaledRecvStream();
  const auto& receivers2 = call_.GetAudioReceiveStreams();
  EXPECT_EQ(0u, receivers2.size());
}

// Test that receiving N unsignaled stream works (streams will be created), and
// that packets are forwarded to them all.
TEST_P(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
  EXPECT_TRUE(SetupChannel());
  unsigned char packet[sizeof(kPcmuFrame)];
  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));

  // Note that SSRC = 0 is not supported.
  for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
    rtc::SetBE32(&packet[8], ssrc);
    DeliverPacket(packet, sizeof(packet));

    // Verify we have one new stream for each loop iteration.
    EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
    EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
    EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
  }

  // Sending on the same SSRCs again should not create new streams.
  for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
    rtc::SetBE32(&packet[8], ssrc);
    DeliverPacket(packet, sizeof(packet));

    EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
    EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
    EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
  }

  // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
  constexpr uint32_t kAnotherSsrc = 667;
  rtc::SetBE32(&packet[8], kAnotherSsrc);
  DeliverPacket(packet, sizeof(packet));

  const auto& streams = call_.GetAudioReceiveStreams();
  EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
  size_t i = 0;
  for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
    EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
    EXPECT_EQ(2, streams[i]->received_packets());
  }
  EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
  EXPECT_EQ(1, streams[i]->received_packets());
  // Sanity check that we've checked all streams.
  EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
}

// Test that a default channel is created even after a signaled stream has been
// added, and that this stream will get any packets for unknown SSRCs.
TEST_P(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
  EXPECT_TRUE(SetupChannel());
  unsigned char packet[sizeof(kPcmuFrame)];
  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));

  // Add a known stream, send packet and verify we got it.
  const uint32_t signaled_ssrc = 1;
  rtc::SetBE32(&packet[8], signaled_ssrc);
  EXPECT_TRUE(AddRecvStream(signaled_ssrc));
  DeliverPacket(packet, sizeof(packet));
  EXPECT_TRUE(
      GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());

  // Note that the first unknown SSRC cannot be 0, because we only support
  // creating receive streams for SSRC!=0.
  const uint32_t unsignaled_ssrc = 7011;
  rtc::SetBE32(&packet[8], unsignaled_ssrc);
  DeliverPacket(packet, sizeof(packet));
  EXPECT_TRUE(
      GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
  EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());

  DeliverPacket(packet, sizeof(packet));
  EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());

  rtc::SetBE32(&packet[8], signaled_ssrc);
  DeliverPacket(packet, sizeof(packet));
  EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
  EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
}

// Two tests to verify that adding a receive stream with the same SSRC as a
// previously added unsignaled stream will only recreate underlying stream
// objects if the stream parameters have changed.
TEST_P(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
  EXPECT_TRUE(SetupChannel());

  // Spawn unsignaled stream with SSRC=1.
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  EXPECT_TRUE(
      GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));

  // Verify that the underlying stream object in Call is not recreated when a
  // stream with SSRC=1 is added.
  const auto& streams = call_.GetAudioReceiveStreams();
  EXPECT_EQ(1u, streams.size());
  int audio_receive_stream_id = streams.front()->id();
  EXPECT_TRUE(AddRecvStream(1));
  EXPECT_EQ(1u, streams.size());
  EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
}

TEST_P(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Updates) {
  EXPECT_TRUE(SetupChannel());

  // Spawn unsignaled stream with SSRC=1.
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  EXPECT_TRUE(
      GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));

  // Verify that the underlying stream object in Call gets updated when a
  // stream with SSRC=1 is added, and which has changed stream parameters.
  const auto& streams = call_.GetAudioReceiveStreams();
  EXPECT_EQ(1u, streams.size());
  // The sync_group id should be empty.
  EXPECT_TRUE(streams.front()->GetConfig().sync_group.empty());

  const std::string new_stream_id("stream_id");
  int audio_receive_stream_id = streams.front()->id();
  cricket::StreamParams stream_params;
  stream_params.ssrcs.push_back(1);
  stream_params.set_stream_ids({new_stream_id});

  EXPECT_TRUE(channel_->AddRecvStream(stream_params));
  EXPECT_EQ(1u, streams.size());
  // The audio receive stream should not have been recreated.
  EXPECT_EQ(audio_receive_stream_id, streams.front()->id());

  // The sync_group id should now match with the new stream params.
  EXPECT_EQ(new_stream_id, streams.front()->GetConfig().sync_group);
}

// Test that AddRecvStream creates new stream.
TEST_P(WebRtcVoiceEngineTestFake, AddRecvStream) {
  EXPECT_TRUE(SetupRecvStream());
  EXPECT_TRUE(AddRecvStream(1));
}

// Test that after adding a recv stream, we do not decode more codecs than
// those previously passed into SetRecvCodecs.
TEST_P(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
}

// Test that we properly clean up any streams that were added, even if
// not explicitly removed.
TEST_P(WebRtcVoiceEngineTestFake, StreamCleanup) {
  EXPECT_TRUE(SetupSendStream());
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(AddRecvStream(1));
  EXPECT_TRUE(AddRecvStream(2));

  EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
  EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
  delete channel_;
  channel_ = NULL;
  EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
  EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
}

TEST_P(WebRtcVoiceEngineTestFake, TestAddRecvStreamSuccessWithZeroSsrc) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(0));
}

TEST_P(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(AddRecvStream(1));
  EXPECT_FALSE(AddRecvStream(1));
}

// Test the InsertDtmf on default send stream as caller.
TEST_P(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
  TestInsertDtmf(0, true, kTelephoneEventCodec1);
}

// Test the InsertDtmf on default send stream as callee
TEST_P(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
  TestInsertDtmf(0, false, kTelephoneEventCodec2);
}

// Test the InsertDtmf on specified send stream as caller.
TEST_P(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
  TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
}

// Test the InsertDtmf on specified send stream as callee.
TEST_P(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
  TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
}

// Test propagation of extmap allow mixed setting.
TEST_P(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
  TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
}
TEST_P(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
  TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
}
TEST_P(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
  TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
}
TEST_P(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
  TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
}

TEST_P(WebRtcVoiceEngineTestFake, SetAudioOptions) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_CALL(*adm_, BuiltInAECIsAvailable())
      .Times(8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, BuiltInAGCIsAvailable())
      .Times(4)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, BuiltInNSIsAvailable())
      .Times(2)
      .WillRepeatedly(Return(false));

  EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
  EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);

  // Nothing set in AudioOptions, so everything should be as default.
  send_parameters_.options = cricket::AudioOptions();
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_TRUE(IsHighPassFilterEnabled());
    EXPECT_TRUE(IsTypingDetectionEnabled());
  }
  EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
  EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);

  // Turn typing detection off.
  send_parameters_.options.typing_detection = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_FALSE(IsTypingDetectionEnabled());
  }

  // Leave typing detection unchanged, but non-default.
  send_parameters_.options.typing_detection = absl::nullopt;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_FALSE(IsTypingDetectionEnabled());
  }

  // Turn typing detection on.
  send_parameters_.options.typing_detection = true;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    EXPECT_TRUE(IsTypingDetectionEnabled());
  }

  // Turn echo cancellation off
  send_parameters_.options.echo_cancellation = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/false);
  }

  // Turn echo cancellation back on, with settings, and make sure
  // nothing else changed.
  send_parameters_.options.echo_cancellation = true;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
  }

  // Turn off echo cancellation and delay agnostic aec.
  send_parameters_.options.echo_cancellation = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/false);
  }

  // Restore AEC to be on to work with the following tests.
  send_parameters_.options.echo_cancellation = true;
  SetSendParameters(send_parameters_);

  // Turn off AGC
  send_parameters_.options.auto_gain_control = false;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(apm_config_.gain_controller1.enabled);
  }

  // Turn AGC back on
  send_parameters_.options.auto_gain_control = true;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_TRUE(apm_config_.gain_controller1.enabled);
  }

  // Turn off other options.
  send_parameters_.options.noise_suppression = false;
  send_parameters_.options.highpass_filter = false;
  send_parameters_.options.stereo_swapping = true;
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(IsHighPassFilterEnabled());
    EXPECT_TRUE(apm_config_.gain_controller1.enabled);
    EXPECT_FALSE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
  }

  // Set options again to ensure it has no impact.
  SetSendParameters(send_parameters_);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_TRUE(apm_config_.gain_controller1.enabled);
    EXPECT_FALSE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
  }
}

TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_CALL(*adm_, BuiltInAECIsAvailable())
      .Times(use_null_apm_ ? 4 : 8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, BuiltInAGCIsAvailable())
      .Times(use_null_apm_ ? 7 : 8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, BuiltInNSIsAvailable())
      .Times(use_null_apm_ ? 5 : 8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, RecordingIsInitialized())
      .Times(2)
      .WillRepeatedly(Return(false));

  EXPECT_CALL(*adm_, Recording()).Times(2).WillRepeatedly(Return(false));
  EXPECT_CALL(*adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));

  std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
      static_cast<cricket::WebRtcVoiceMediaChannel*>(
          engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
                                      cricket::AudioOptions(),
                                      webrtc::CryptoOptions())));
  std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
      static_cast<cricket::WebRtcVoiceMediaChannel*>(
          engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
                                      cricket::AudioOptions(),
                                      webrtc::CryptoOptions())));

  // Have to add a stream to make SetSend work.
  cricket::StreamParams stream1;
  stream1.ssrcs.push_back(1);
  channel1->AddSendStream(stream1);
  cricket::StreamParams stream2;
  stream2.ssrcs.push_back(2);
  channel2->AddSendStream(stream2);

  // AEC and AGC and NS
  cricket::AudioSendParameters parameters_options_all = send_parameters_;
  parameters_options_all.options.echo_cancellation = true;
  parameters_options_all.options.auto_gain_control = true;
  parameters_options_all.options.noise_suppression = true;
  EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    VerifyGainControlEnabledCorrectly();
    EXPECT_TRUE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
    EXPECT_EQ(parameters_options_all.options, channel1->options());
    EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
    VerifyEchoCancellationSettings(/*enabled=*/true);
    VerifyGainControlEnabledCorrectly();
    EXPECT_EQ(parameters_options_all.options, channel2->options());
  }

  // unset NS
  cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
  parameters_options_no_ns.options.noise_suppression = false;
  EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
  cricket::AudioOptions expected_options = parameters_options_all.options;
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
    VerifyGainControlEnabledCorrectly();
    expected_options.echo_cancellation = true;
    expected_options.auto_gain_control = true;
    expected_options.noise_suppression = false;
    EXPECT_EQ(expected_options, channel1->options());
  }

  // unset AGC
  cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
  parameters_options_no_agc.options.auto_gain_control = false;
  EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(apm_config_.gain_controller1.enabled);
    EXPECT_TRUE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
    expected_options.echo_cancellation = true;
    expected_options.auto_gain_control = false;
    expected_options.noise_suppression = true;
    EXPECT_EQ(expected_options, channel2->options());
  }

  EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    VerifyGainControlEnabledCorrectly();
    EXPECT_TRUE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
  }

  channel1->SetSend(true);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    VerifyGainControlEnabledCorrectly();
    EXPECT_FALSE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
  }

  channel2->SetSend(true);
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(apm_config_.gain_controller1.enabled);
    EXPECT_TRUE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
  }

  // Make sure settings take effect while we are sending.
  cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
      send_parameters_;
  parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
  parameters_options_no_agc_nor_ns.options.noise_suppression = false;
  EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
  if (!use_null_apm_) {
    VerifyEchoCancellationSettings(/*enabled=*/true);
    EXPECT_FALSE(apm_config_.gain_controller1.enabled);
    EXPECT_FALSE(apm_config_.noise_suppression.enabled);
    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
    expected_options.echo_cancellation = true;
    expected_options.auto_gain_control = false;
    expected_options.noise_suppression = false;
    EXPECT_EQ(expected_options, channel2->options());
  }
}

// This test verifies DSCP settings are properly applied on voice media channel.
TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
  EXPECT_TRUE(SetupSendStream());
  cricket::FakeNetworkInterface network_interface;
  cricket::MediaConfig config;
  std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
  webrtc::RtpParameters parameters;

  channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
      engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
                                  webrtc::CryptoOptions())));
  channel->SetInterface(&network_interface);
  // Default value when DSCP is disabled should be DSCP_DEFAULT.
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
  channel->SetInterface(nullptr);

  config.enable_dscp = true;
  channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
      engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
                                  webrtc::CryptoOptions())));
  channel->SetInterface(&network_interface);
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());

  // Create a send stream to configure
  EXPECT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
  parameters = channel->GetRtpSendParameters(kSsrcZ);
  ASSERT_FALSE(parameters.encodings.empty());

  // Various priorities map to various dscp values.
  parameters.encodings[0].network_priority = webrtc::Priority::kHigh;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
  EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
  parameters.encodings[0].network_priority = webrtc::Priority::kVeryLow;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
  EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());

  // Packets should also self-identify their dscp in PacketOptions.
  const uint8_t kData[10] = {0};
  EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
  EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
  channel->SetInterface(nullptr);

  // Verify that setting the option to false resets the
  // DiffServCodePoint.
  config.enable_dscp = false;
  channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
      engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
                                  webrtc::CryptoOptions())));
  channel->SetInterface(&network_interface);
  // Default value when DSCP is disabled should be DSCP_DEFAULT.
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());

  channel->SetInterface(nullptr);
}

TEST_P(WebRtcVoiceEngineTestFake, SetOutputVolume) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
  cricket::StreamParams stream;
  stream.ssrcs.push_back(kSsrcY);
  EXPECT_TRUE(channel_->AddRecvStream(stream));
  EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
  EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
  EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
}

TEST_P(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
  EXPECT_TRUE(SetupChannel());

  // Spawn an unsignaled stream by sending a packet - gain should be 1.
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());

  // Should remember the volume "2" which will be set on new unsignaled streams,
  // and also set the gain to 2 on existing unsignaled streams.
  EXPECT_TRUE(channel_->SetDefaultOutputVolume(2));
  EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());

  // Spawn an unsignaled stream by sending a packet - gain should be 2.
  unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
  memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
  rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
  DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
  EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());

  // Setting gain for all unsignaled streams.
  EXPECT_TRUE(channel_->SetDefaultOutputVolume(3));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
  }
  EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());

  // Setting gain on an individual stream affects only that.
  EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
  }
  EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
}

TEST_P(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

  cricket::StreamParams stream;
  stream.ssrcs.push_back(kSsrcY);
  EXPECT_TRUE(channel_->AddRecvStream(stream));
  EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
  EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
}

TEST_P(WebRtcVoiceEngineTestFake,
       BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
  // Here base minimum delay is abbreviated to delay in comments for shortness.
  EXPECT_TRUE(SetupChannel());

  // Spawn an unsignaled stream by sending a packet - delay should be 0.
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

  // Check that default value for unsignaled streams is 0.
  EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));

  // Should remember the delay 100 which will be set on new unsignaled streams,
  // and also set the delay to 100 on existing unsignaled streams.
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
  EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

  // Spawn an unsignaled stream by sending a packet - delay should be 100.
  unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
  memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
  rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
  DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
  EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));

  // Setting delay with SSRC=0 should affect all unsignaled streams.
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
  }
  EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));

  // Setting delay on an individual stream affects only that.
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
  }
  EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
  EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
}

TEST_P(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
  const uint32_t kAudioSsrc = 123;
  const std::string kStreamId = "AvSyncLabel";

  EXPECT_TRUE(SetupSendStream());
  cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
  sp.set_stream_ids({kStreamId});
  // Creating two channels to make sure that sync label is set properly for both
  // the default voice channel and following ones.
  EXPECT_TRUE(channel_->AddRecvStream(sp));
  sp.ssrcs[0] += 1;
  EXPECT_TRUE(channel_->AddRecvStream(sp));

  ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
  EXPECT_EQ(kStreamId,
            call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
      << "SyncGroup should be set based on stream id";
  EXPECT_EQ(kStreamId,
            call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
      << "SyncGroup should be set based on stream id";
}

// TODO(solenberg): Remove, once recv streams are configured through Call.
//                  (This is then covered by TestSetRecvRtpHeaderExtensions.)
TEST_P(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
  // Test that setting the header extensions results in the expected state
  // changes on an associated Call.
  std::vector<uint32_t> ssrcs;
  ssrcs.push_back(223);
  ssrcs.push_back(224);

  EXPECT_TRUE(SetupSendStream());
  SetSendParameters(send_parameters_);
  for (uint32_t ssrc : ssrcs) {
    EXPECT_TRUE(
        channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
  }

  EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
  for (uint32_t ssrc : ssrcs) {
    const auto* s = call_.GetAudioReceiveStream(ssrc);
    EXPECT_NE(nullptr, s);
    EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
  }

  // Set up receive extensions.
  const std::vector<webrtc::RtpExtension> header_extensions =
      GetDefaultEnabledRtpHeaderExtensions(*engine_);
  cricket::AudioRecvParameters recv_parameters;
  recv_parameters.extensions = header_extensions;
  channel_->SetRecvParameters(recv_parameters);
  EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
  for (uint32_t ssrc : ssrcs) {
    const auto* s = call_.GetAudioReceiveStream(ssrc);
    EXPECT_NE(nullptr, s);
    const auto& s_exts = s->GetConfig().rtp.extensions;
    EXPECT_EQ(header_extensions.size(), s_exts.size());
    for (const auto& e_ext : header_extensions) {
      for (const auto& s_ext : s_exts) {
        if (e_ext.id == s_ext.id) {
          EXPECT_EQ(e_ext.uri, s_ext.uri);
        }
      }
    }
  }

  // Disable receive extensions.
  channel_->SetRecvParameters(cricket::AudioRecvParameters());
  for (uint32_t ssrc : ssrcs) {
    const auto* s = call_.GetAudioReceiveStream(ssrc);
    EXPECT_NE(nullptr, s);
    EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
  }
}

TEST_P(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
  // Test that packets are forwarded to the Call when configured accordingly.
  const uint32_t kAudioSsrc = 1;
  rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
  static const unsigned char kRtcp[] = {
      0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));

  EXPECT_TRUE(SetupSendStream());
  cricket::WebRtcVoiceMediaChannel* media_channel =
      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(media_channel->AddRecvStream(
      cricket::StreamParams::CreateLegacy(kAudioSsrc)));

  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  const cricket::FakeAudioReceiveStream* s =
      call_.GetAudioReceiveStream(kAudioSsrc);
  EXPECT_EQ(0, s->received_packets());
  channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
  rtc::Thread::Current()->ProcessMessages(0);

  EXPECT_EQ(1, s->received_packets());
}

// All receive channels should be associated with the first send channel,
// since they do not send RTCP SR.
TEST_P(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
  EXPECT_TRUE(AddRecvStream(kSsrcW));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
}

TEST_P(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
  EXPECT_TRUE(SetupRecvStream());
  EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
  EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
  EXPECT_TRUE(AddRecvStream(kSsrcZ));
  EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
  EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
  EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
}

TEST_P(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
  EXPECT_TRUE(SetupChannel());
  std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
  std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());

  // Setting the sink before a recv stream exists should do nothing.
  channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());

  // Now try actually setting the sink.
  channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
  EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());

  // Now try resetting it.
  channel_->SetRawAudioSink(kSsrcX, nullptr);
  EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
}

TEST_P(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
  EXPECT_TRUE(SetupChannel());
  std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
  std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
  std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
  std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());

  // Should be able to set a default sink even when no stream exists.
  channel_->SetDefaultRawAudioSink(std::move(fake_sink_1));

  // Spawn an unsignaled stream by sending a packet - it should be assigned the
  // default sink.
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());

  // Try resetting the default sink.
  channel_->SetDefaultRawAudioSink(nullptr);
  EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());

  // Try setting the default sink while the default stream exists.
  channel_->SetDefaultRawAudioSink(std::move(fake_sink_2));
  EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());

  // If we remove and add a default stream, it should get the same sink.
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
  EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());

  // Spawn another unsignaled stream - it should be assigned the default sink
  // and the previous unsignaled stream should lose it.
  unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
  memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
  rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
  DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
  }
  EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());

  // Reset the default sink - the second unsignaled stream should lose it.
  channel_->SetDefaultRawAudioSink(nullptr);
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
  }
  EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());

  // Try setting the default sink while two streams exists.
  channel_->SetDefaultRawAudioSink(std::move(fake_sink_3));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
  }
  EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());

  // Try setting the sink for the first unsignaled stream using its known SSRC.
  channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
  }
  EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
  }
}

// Test that, just like the video channel, the voice channel communicates the
// network state to the call.
TEST_P(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
  EXPECT_TRUE(SetupChannel());

  EXPECT_EQ(webrtc::kNetworkUp,
            call_.GetNetworkState(webrtc::MediaType::AUDIO));
  EXPECT_EQ(webrtc::kNetworkUp,
            call_.GetNetworkState(webrtc::MediaType::VIDEO));

  channel_->OnReadyToSend(false);
  EXPECT_EQ(webrtc::kNetworkDown,
            call_.GetNetworkState(webrtc::MediaType::AUDIO));
  EXPECT_EQ(webrtc::kNetworkUp,
            call_.GetNetworkState(webrtc::MediaType::VIDEO));

  channel_->OnReadyToSend(true);
  EXPECT_EQ(webrtc::kNetworkUp,
            call_.GetNetworkState(webrtc::MediaType::AUDIO));
  EXPECT_EQ(webrtc::kNetworkUp,
            call_.GetNetworkState(webrtc::MediaType::VIDEO));
}

// Test that playout is still started after changing parameters
TEST_P(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
  SetupRecvStream();
  channel_->SetPlayout(true);
  EXPECT_TRUE(GetRecvStream(kSsrcX).started());

  // Changing RTP header extensions will recreate the AudioReceiveStream.
  cricket::AudioRecvParameters parameters;
  parameters.extensions.push_back(
      webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
  channel_->SetRecvParameters(parameters);

  EXPECT_TRUE(GetRecvStream(kSsrcX).started());
}

// Tests when GetSources is called with non-existing ssrc, it will return an
// empty list of RtpSource without crashing.
TEST_P(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
  // Setup an recv stream with `kSsrcX`.
  SetupRecvStream();
  cricket::WebRtcVoiceMediaChannel* media_channel =
      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
  // Call GetSources with `kSsrcY` which doesn't exist.
  std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
  EXPECT_EQ(0u, sources.size());
}

// Tests that the library initializes and shuts down properly.
TEST(WebRtcVoiceEngineTest, StartupShutdown) {
  for (bool use_null_apm : {false, true}) {
    // If the VoiceEngine wants to gather available codecs early, that's fine
    // but we never want it to create a decoder at this stage.
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateNice();
    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
    webrtc::FieldTrialBasedConfig field_trials;
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
        nullptr, field_trials);
    engine.Init();
    webrtc::RtcEventLogNull event_log;
    webrtc::Call::Config call_config(&event_log);
    call_config.trials = &field_trials;
    call_config.task_queue_factory = task_queue_factory.get();
    auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
    cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
        call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
        webrtc::CryptoOptions());
    EXPECT_TRUE(channel != nullptr);
    delete channel;
  }
}

// Tests that reference counting on the external ADM is correct.
TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
  for (bool use_null_apm : {false, true}) {
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    auto adm = rtc::make_ref_counted<
        ::testing::NiceMock<webrtc::test::MockAudioDeviceModule>>();
    {
      rtc::scoped_refptr<webrtc::AudioProcessing> apm =
          use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
      webrtc::FieldTrialBasedConfig field_trials;
      cricket::WebRtcVoiceEngine engine(
          task_queue_factory.get(), adm,
          webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
          webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
          nullptr, field_trials);
      engine.Init();
      webrtc::RtcEventLogNull event_log;
      webrtc::Call::Config call_config(&event_log);
      call_config.trials = &field_trials;
      call_config.task_queue_factory = task_queue_factory.get();
      auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
      cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
          call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
          webrtc::CryptoOptions());
      EXPECT_TRUE(channel != nullptr);
      delete channel;
    }
    // The engine/channel should have dropped their references.
    EXPECT_EQ(adm.release()->Release(),
              rtc::RefCountReleaseStatus::kDroppedLastRef);
  }
}

// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
  for (bool use_null_apm : {false, true}) {
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    // TODO(ossu): Why are the payload types of codecs with non-static payload
    // type assignments checked here? It shouldn't really matter.
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateNice();
    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
    webrtc::FieldTrialBasedConfig field_trials;
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
        nullptr, field_trials);
    engine.Init();
    for (const cricket::AudioCodec& codec : engine.send_codecs()) {
      auto is_codec = [&codec](const char* name, int clockrate = 0) {
        return absl::EqualsIgnoreCase(codec.name, name) &&
               (clockrate == 0 || codec.clockrate == clockrate);
      };
      if (is_codec("CN", 16000)) {
        EXPECT_EQ(105, codec.id);
      } else if (is_codec("CN", 32000)) {
        EXPECT_EQ(106, codec.id);
      } else if (is_codec("ISAC", 16000)) {
        EXPECT_EQ(103, codec.id);
      } else if (is_codec("ISAC", 32000)) {
        EXPECT_EQ(104, codec.id);
      } else if (is_codec("G722", 8000)) {
        EXPECT_EQ(9, codec.id);
      } else if (is_codec("telephone-event", 8000)) {
        EXPECT_EQ(126, codec.id);
        // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
        // Remove these checks once both send and receive side assigns payload
        // types dynamically.
      } else if (is_codec("telephone-event", 16000)) {
        EXPECT_EQ(113, codec.id);
      } else if (is_codec("telephone-event", 32000)) {
        EXPECT_EQ(112, codec.id);
      } else if (is_codec("telephone-event", 48000)) {
        EXPECT_EQ(110, codec.id);
      } else if (is_codec("opus")) {
        EXPECT_EQ(111, codec.id);
        ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
        EXPECT_EQ("10", codec.params.find("minptime")->second);
        ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
        EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
      }
    }
  }
}

// Tests that VoE supports at least 32 channels
TEST(WebRtcVoiceEngineTest, Has32Channels) {
  for (bool use_null_apm : {false, true}) {
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateNice();
    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
    webrtc::FieldTrialBasedConfig field_trials;
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
        nullptr, field_trials);
    engine.Init();
    webrtc::RtcEventLogNull event_log;
    webrtc::Call::Config call_config(&event_log);
    call_config.trials = &field_trials;
    call_config.task_queue_factory = task_queue_factory.get();
    auto call = absl::WrapUnique(webrtc::Call::Create(call_config));

    cricket::VoiceMediaChannel* channels[32];
    size_t num_channels = 0;
    while (num_channels < arraysize(channels)) {
      cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
          call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
          webrtc::CryptoOptions());
      if (!channel)
        break;
      channels[num_channels++] = channel;
    }

    size_t expected = arraysize(channels);
    EXPECT_EQ(expected, num_channels);

    while (num_channels > 0) {
      delete channels[--num_channels];
    }
  }
}

// Test that we set our preferred codecs properly.
TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
  for (bool use_null_apm : {false, true}) {
    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    // TODO(ossu): I'm not sure of the intent of this test. It's either:
    // - Check that our builtin codecs are usable by Channel.
    // - The codecs provided by the engine is usable by Channel.
    // It does not check that the codecs in the RecvParameters are actually
    // what we sent in - though it's probably reasonable to expect so, if
    // SetRecvParameters returns true.
    // I think it will become clear once audio decoder injection is completed.
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateNice();
    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
    webrtc::FieldTrialBasedConfig field_trials;
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm, nullptr,
        field_trials);
    engine.Init();
    webrtc::RtcEventLogNull event_log;
    webrtc::Call::Config call_config(&event_log);
    call_config.trials = &field_trials;
    call_config.task_queue_factory = task_queue_factory.get();
    auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
    cricket::WebRtcVoiceMediaChannel channel(
        &engine, cricket::MediaConfig(), cricket::AudioOptions(),
        webrtc::CryptoOptions(), call.get());
    cricket::AudioRecvParameters parameters;
    parameters.codecs = engine.recv_codecs();
    EXPECT_TRUE(channel.SetRecvParameters(parameters));
  }
}

TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
  for (bool use_null_apm : {false, true}) {
    std::vector<webrtc::AudioCodecSpec> specs;
    webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
                                 {48000, 2, 16000, 10000, 20000}};
    spec1.info.allow_comfort_noise = false;
    spec1.info.supports_network_adaption = true;
    specs.push_back(spec1);
    webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
    spec2.info.allow_comfort_noise = false;
    specs.push_back(spec2);
    specs.push_back(webrtc::AudioCodecSpec{
        {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
        {16000, 1, 13300}});
    specs.push_back(
        webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
    specs.push_back(
        webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});

    std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
        webrtc::CreateDefaultTaskQueueFactory();
    rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
    rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
        rtc::make_ref_counted<webrtc::MockAudioDecoderFactory>();
    EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
        .WillOnce(Return(specs));
    rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
        webrtc::test::MockAudioDeviceModule::CreateNice();

    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create();
    webrtc::FieldTrialBasedConfig field_trials;
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), adm, unused_encoder_factory,
        mock_decoder_factory, nullptr, apm, nullptr, field_trials);
    engine.Init();
    auto codecs = engine.recv_codecs();
    EXPECT_EQ(11u, codecs.size());

    // Rather than just ASSERTing that there are enough codecs, ensure that we
    // can check the actual values safely, to provide better test results.
    auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
      static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
      if (codecs.size() > index)
        return codecs[index];
      return missing_codec;
    };

    // Ensure the general codecs are generated first and in order.
    for (size_t i = 0; i != specs.size(); ++i) {
      EXPECT_EQ(specs[i].format.name, get_codec(i).name);
      EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
      EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
      EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
    }

    // Find the index of a codec, or -1 if not found, so that we can easily
    // check supplementary codecs are ordered after the general codecs.
    auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
      for (size_t i = 0; i != codecs.size(); ++i) {
        const cricket::AudioCodec& codec = codecs[i];
        if (absl::EqualsIgnoreCase(codec.name, format.name) &&
            codec.clockrate == format.clockrate_hz &&
            codec.channels == format.num_channels) {
          return rtc::checked_cast<int>(i);
        }
      }
      return -1;
    };

    // Ensure all supplementary codecs are generated last. Their internal
    // ordering is not important. Without this cast, the comparison turned
    // unsigned and, thus, failed for -1.
    const int num_specs = static_cast<int>(specs.size());
    EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
    EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
    EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
    EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
    EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
    EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
    EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
  }
}
