/*
 *  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_mixer/audio_mixer_impl.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
#include "test/mock_audio_encoder_factory.h"
#include "test/scoped_key_value_config.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 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.get());
    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.get(),
          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()
      : 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_(&field_trials_) {
    // AudioDeviceModule.
    AdmSetupExpectations(adm_.get());

    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_.get(), encoder_factory, decoder_factory,
        nullptr, apm_, nullptr, field_trials_));
    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(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());
    send_channel_ = std::make_unique<cricket::VoiceMediaSendChannel>(channel_);
    receive_channel_ =
        std::make_unique<cricket::VoiceMediaReceiveChannel>(channel_);
    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 (!send_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 receive_channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(ssrc));
  }

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

  void DeliverPacket(const void* data, int len) {
    webrtc::RtpPacketReceived packet;
    packet.Parse(reinterpret_cast<const uint8_t*>(data), len);
    receive_channel_->OnPacketReceived(packet);
    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::AudioReceiveStreamInterface::Config& GetRecvStreamConfig(
      uint32_t ssrc) {
    return GetRecvStream(ssrc).GetConfig();
  }

  void SetSend(bool enable) {
    ASSERT_TRUE(channel_);
    if (enable) {
      EXPECT_CALL(*adm_, RecordingIsInitialized())
          .Times(::testing::AtMost(1))
          .WillOnce(Return(false));
      EXPECT_CALL(*adm_, Recording())
          .Times(::testing::AtMost(1))
          .WillOnce(Return(false));
      EXPECT_CALL(*adm_, InitRecording())
          .Times(::testing::AtMost(1))
          .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(send_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(send_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(send_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(send_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 =
        send_channel_->GetRtpSendParameters(ssrc);
    EXPECT_EQ(1UL, parameters.encodings.size());

    parameters.encodings[0].max_bitrate_bps = bitrate;
    return send_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;
  }

  int GetMaxBitrate(int32_t ssrc) {
    return GetSendStreamConfig(ssrc).max_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 =
        send_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));
    EXPECT_EQ(expected_codec_bitrate, GetMaxBitrate(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(send_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;
    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);
  }

  webrtc::AudioReceiveStreamInterface::Stats GetAudioReceiveStreamStats()
      const {
    webrtc::AudioReceiveStreamInterface::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(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::VoiceMediaSendInfo& send_info,
      const cricket::VoiceMediaReceiveInfo& receive_info) const {
    EXPECT_EQ(send_parameters_.codecs.size(), send_info.send_codecs.size());
    for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
      ASSERT_EQ(send_info.send_codecs.count(codec.id), 1U);
      EXPECT_EQ(send_info.send_codecs.find(codec.id)->second,
                codec.ToCodecParameters());
    }
    EXPECT_EQ(recv_parameters_.codecs.size(),
              receive_info.receive_codecs.size());
    for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
      ASSERT_EQ(receive_info.receive_codecs.count(codec.id), 1U);
      EXPECT_EQ(receive_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);
  }

  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;
  }

 protected:
  rtc::AutoThread main_thread_;
  const bool use_null_apm_;
  webrtc::test::ScopedKeyValueConfig field_trials_;
  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;
  std::unique_ptr<cricket::VoiceMediaSendChannel> send_channel_;
  std::unique_ptr<cricket::VoiceMediaReceiveChannel> receive_channel_;
  cricket::AudioSendParameters send_parameters_;
  cricket::AudioRecvParameters recv_parameters_;
  FakeAudioSource fake_source_;
  webrtc::AudioProcessing::Config apm_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(send_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::AudioReceiveStreamInterface::Config& config =
      GetRecvStreamConfig(kSsrcX);
  EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
  EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
  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(kOpusCodec);
  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, {"OPUS", 48000, 2}},
                   {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(kOpusCodec);
  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(kOpusCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[1].id = kOpusCodec.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(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}}, {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(kPcmuCodec);
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[1].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}},
                   {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(kPcmuCodec);
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[1].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}},
                   {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(kOpusCodec);
  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, {"OPUS", 48000, 2}},
                     {126, {"telephone-event", 8000, 1}},
                     {107, {"telephone-event", 32000, 1}}})));
  }
}

TEST_P(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  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("opus", 48000, 2), 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(kPcmuCodec);
  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 = kPcmuCodec.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(kPcmuCodec);
  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(kOpusCodec);
  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_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.

  // 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());

  // 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(send_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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(0u, nonexistent_parameters.encodings.size());

  nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(
      send_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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  // Two or more encodings should result in failure.
  parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(send_channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  // Zero encodings should also fail.
  parameters.encodings.clear();
  EXPECT_FALSE(send_channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
}

// Changing the SSRC through RtpParameters is not allowed.
TEST_P(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters parameters =
      send_channel_->GetRtpSendParameters(kSsrcX);
  parameters.encodings[0].ssrc = 0xdeadbeef;
  EXPECT_FALSE(send_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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_TRUE(parameters.encodings[0].active);
  parameters.encodings[0].active = false;
  EXPECT_TRUE(send_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(send_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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_FALSE(parameters.encodings[0].adaptive_ptime);
  parameters.encodings[0].adaptive_ptime = true;
  EXPECT_TRUE(send_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(send_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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  parameters.encodings[0].adaptive_ptime = false;
  EXPECT_TRUE(send_channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
            GetAudioNetworkAdaptorConfig(kSsrcX));
}

TEST_P(WebRtcVoiceEngineTestFake, AdaptivePtimeFieldTrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      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(send_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(kOpusCodec);
  parameters.codecs.push_back(kPcmuCodec);
  SetSendParameters(parameters);

  webrtc::RtpParameters rtp_parameters =
      send_channel_->GetRtpSendParameters(kSsrcX);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(kOpusCodec.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 =
      send_channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
}

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

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

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

  webrtc::RTCError result =
      send_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 =
      send_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(kOpusCodec);
  parameters.codecs.push_back(kPcmuCodec);
  SetSendParameters(parameters);

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

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

  // ... And this shouldn't change the params returned by GetRtpSendParameters.
  webrtc::RtpParameters new_params =
      send_channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(initial_params, send_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 =
      send_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(send_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 =
      send_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(
      send_channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
  rtp_parameters.encodings[0].bitrate_priority = -1.0;
  EXPECT_FALSE(
      send_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 =
      send_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(send_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, send_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(kOpusCodec);
  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(kOpusCodec.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(kOpusCodec);
  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(kOpusCodec);
  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_P(WebRtcVoiceEngineTestFake, OnPacketReceivedIdentifiesExtensions) {
  ASSERT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters = recv_parameters_;
  parameters.extensions.push_back(
      RtpExtension(RtpExtension::kAudioLevelUri, /*id=*/1));
  ASSERT_TRUE(channel_->SetRecvParameters(parameters));
  webrtc::RtpHeaderExtensionMap extension_map(parameters.extensions);
  webrtc::RtpPacketReceived reference_packet(&extension_map);
  constexpr uint8_t kAudioLevel = 123;
  reference_packet.SetExtension<webrtc::AudioLevel>(/*voice_activity=*/true,
                                                    kAudioLevel);
  //  Create a packet without the extension map but with the same content.
  webrtc::RtpPacketReceived received_packet;
  ASSERT_TRUE(received_packet.Parse(reference_packet.Buffer()));

  receive_channel_->OnPacketReceived(received_packet);
  rtc::Thread::Current()->ProcessMessages(0);

  bool voice_activity;
  uint8_t audio_level;
  EXPECT_TRUE(call_.last_received_rtp_packet().GetExtension<webrtc::AudioLevel>(
      &voice_activity, &audio_level));
  EXPECT_EQ(audio_level, kAudioLevel);
}

// Test that we apply codecs properly.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecs) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  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("OPUS", 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_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(112, send_codec_spec2.red_payload_type);
  }
  parameters.codecs[0].params[""] += "/111";
  SetSendParameters(parameters);
  const auto& send_codec_spec3 = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(111, send_codec_spec3.payload_type);
  EXPECT_STRCASEEQ("opus", send_codec_spec3.format.name.c_str());
  EXPECT_EQ(absl::nullopt, send_codec_spec3.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(kOpusCodec);
  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(send_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(kOpusCodec);
  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 that we can switch back and forth between Opus and PCMU with CN.
TEST_P(WebRtcVoiceEngineTestFake, SetSendCodecsOpusPcmuSwitching) {
  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 pcmu_parameters;
  pcmu_parameters.codecs.push_back(kPcmuCodec);
  pcmu_parameters.codecs.push_back(kCn16000Codec);
  pcmu_parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(pcmu_parameters);
  {
    const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_EQ(0, spec.payload_type);
    EXPECT_STRCASEEQ("PCMU", 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(kPcmuCodec);
  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(kOpusCodec);
  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("OPUS", 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(kOpusCodec);
  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(kCn8000Codec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs[0].id = 98;  // narrowband CN
  SetSendParameters(parameters);
  const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(0, send_codec_spec.payload_type);
  EXPECT_STRCASEEQ("PCMU", 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(kPcmuCodec);
  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;  // narrowband CN
  parameters.codecs[3].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("PCMU", 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(kPcmuCodec);
  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;  // narrowband CN
  parameters.codecs[3].id = 98;  // DTMF
  SetSendParameters(parameters);
  EXPECT_TRUE(send_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("PCMU", 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 PCMU(8K) and CN(16K). VAD should not be activated.
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[1].id = 97;
  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 OPUS(48K) and CN(8K). VAD should not be activated.
  parameters.codecs[0] = kOpusCodec;
  SetSendParameters(parameters);
  {
    const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
    EXPECT_STRCASEEQ("OPUS", 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(kPcmuCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs[0].name = "PcMu";
  parameters.codecs[0].id = 96;
  parameters.codecs[2].id = 97;  // narrowband CN
  parameters.codecs[3].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("PCMU", 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(send_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(send_channel_->RemoveSendStream(ssrc));
    EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
    EXPECT_FALSE(send_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(send_channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(ssrc)));
  }

  cricket::AudioSendParameters parameters;
  // Set PCMU and CN(8K). VAD should be activated.
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kCn8000Codec);
  parameters.codecs[1].id = 97;
  SetSendParameters(parameters);

  // Verify PCMU 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("PCMU", 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;
  parameters.codecs[1] = kCn16000Codec;
  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(send_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(send_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::VoiceMediaSendInfo send_info;
    cricket::VoiceMediaReceiveInfo receive_info;
    EXPECT_EQ(true, channel_->GetSendStats(&send_info));
    EXPECT_EQ(true, channel_->GetReceiveStats(
                        &receive_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)),
              send_info.senders.size());
    for (const auto& sender : send_info.senders) {
      VerifyVoiceSenderInfo(sender, false);
    }
    VerifyVoiceSendRecvCodecs(send_info, receive_info);

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

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

  // Deliver a new packet - a default receive stream should be created and we
  // should see stats again.
  {
    cricket::VoiceMediaSendInfo send_info;
    cricket::VoiceMediaReceiveInfo receive_info;
    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
    SetAudioReceiveStreamStats();
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    EXPECT_EQ(true, channel_->GetSendStats(&send_info));
    EXPECT_EQ(true, channel_->GetReceiveStats(
                        &receive_info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)),
              send_info.senders.size());
    EXPECT_EQ(1u, receive_info.receivers.size());
    VerifyVoiceReceiverInfo(receive_info.receivers[0]);
    VerifyVoiceSendRecvCodecs(send_info, receive_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(receive_channel_->RemoveRecvStream(kSsrcZ));
  EXPECT_TRUE(receive_channel_->RemoveRecvStream(kSsrcY));
}

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));
}

// 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::VoiceMediaSendInfo send_info;
    cricket::VoiceMediaReceiveInfo receive_info;
    EXPECT_EQ(true, channel_->GetSendStats(&send_info));
    EXPECT_EQ(true, channel_->GetReceiveStats(
                        &receive_info, /*get_and_clear_legacy_stats=*/true));

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

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

  // Remove the kSsrcY stream. No receiver stats.
  {
    EXPECT_TRUE(receive_channel_->RemoveRecvStream(kSsrcY));
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    cricket::VoiceMediaSendInfo send_info;
    cricket::VoiceMediaReceiveInfo receive_info;
    EXPECT_EQ(true, channel_->GetSendStats(&send_info));
    EXPECT_EQ(true, channel_->GetReceiveStats(
                        &receive_info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(1u, send_info.senders.size());
    EXPECT_EQ(0u, receive_info.receivers.size());
  }

  // Deliver a new packet - a default receive stream should be created and we
  // should see stats again.
  {
    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
    SetAudioReceiveStreamStats();
    EXPECT_CALL(*adm_, GetPlayoutUnderrunCount()).WillOnce(Return(0));
    cricket::VoiceMediaSendInfo send_info;
    cricket::VoiceMediaReceiveInfo receive_info;
    EXPECT_EQ(true, channel_->GetSendStats(&send_info));
    EXPECT_EQ(true, channel_->GetReceiveStats(
                        &receive_info, /*get_and_clear_legacy_stats=*/true));
    EXPECT_EQ(1u, send_info.senders.size());
    EXPECT_EQ(1u, receive_info.receivers.size());
    VerifyVoiceReceiverInfo(receive_info.receivers[0]);
    VerifyVoiceSendRecvCodecs(send_info, receive_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(send_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(receive_channel_->RemoveRecvStream(ssrc3));
  EXPECT_TRUE(receive_channel_->RemoveRecvStream(ssrc2));
  EXPECT_TRUE(receive_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(receive_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.
  receive_channel_->ResetUnsignaledRecvStream();
  receive_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.
  receive_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(receive_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(kOpusCodec);
  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}}, {111, {"OPUS", 48000, 2}}})));
}

// 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_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
  EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);

  // 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, InitRecordingOnSend) {
  EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
  EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
  EXPECT_CALL(*adm_, InitRecording()).Times(1);

  std::unique_ptr<cricket::VoiceMediaChannel> channel(
      engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
                                  cricket::AudioOptions(),
                                  webrtc::CryptoOptions()));

  channel->SetSend(true);
}

TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) {
  EXPECT_CALL(*adm_, RecordingIsInitialized()).Times(0);
  EXPECT_CALL(*adm_, Recording()).Times(0);
  EXPECT_CALL(*adm_, InitRecording()).Times(0);

  cricket::AudioOptions options;
  options.init_recording_on_send = false;

  std::unique_ptr<cricket::VoiceMediaChannel> channel(
      engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options,
                                  webrtc::CryptoOptions()));

  channel->SetSend(true);
}

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, nullptr).ok());
  EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
  parameters.encodings[0].network_priority = webrtc::Priority::kVeryLow;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters, nullptr).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(receive_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(receive_channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
  EXPECT_FALSE(
      receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

  cricket::StreamParams stream;
  stream.ssrcs.push_back(kSsrcY);
  EXPECT_TRUE(receive_channel_->AddRecvStream(stream));
  EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
  EXPECT_TRUE(receive_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, receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(
      receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

  // Check that default value for unsignaled streams is 0.
  EXPECT_EQ(
      0, receive_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(receive_channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
  EXPECT_EQ(
      100, receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(
      receive_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, receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));

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

  // Setting delay on an individual stream affects only that.
  EXPECT_TRUE(receive_channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
  if (kMaxUnsignaledRecvStreams > 1) {
    EXPECT_EQ(
        300,
        receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
  }
  EXPECT_EQ(
      400, receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
  EXPECT_EQ(
      300, receive_channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
  // Check that it doesn't provide default values for unknown ssrc.
  EXPECT_FALSE(
      receive_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(receive_channel_->AddRecvStream(sp));
  sp.ssrcs[0] += 1;
  EXPECT_TRUE(receive_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(receive_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());
  webrtc::RtpPacketReceived parsed_packet;
  RTC_CHECK(parsed_packet.Parse(kPcmuPacket));
  receive_channel_->OnPacketReceived(parsed_packet);
  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(send_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(send_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(send_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(receive_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));

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

  send_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
  // AudioReceiveStreamInterface.
  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) {
  rtc::AutoThread main_thread;
  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.get(),
        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) {
  rtc::AutoThread main_thread;
  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.get(),
          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 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.get(),
        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("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) {
  rtc::AutoThread main_thread;
  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.get(),
        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) {
  rtc::AutoThread main_thread;
  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.get(),
        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, SetRtpSendParametersMaxBitrate) {
  rtc::AutoThread main_thread;
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
      webrtc::CreateDefaultTaskQueueFactory();
  rtc::scoped_refptr<webrtc::test::MockAudioDeviceModule> adm =
      webrtc::test::MockAudioDeviceModule::CreateNice();
  webrtc::FieldTrialBasedConfig field_trials;
  FakeAudioSource source;
  cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), adm.get(),
                                    webrtc::CreateBuiltinAudioEncoderFactory(),
                                    webrtc::CreateBuiltinAudioDecoderFactory(),
                                    nullptr, nullptr, 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();
  {
    webrtc::AudioState::Config config;
    config.audio_mixer = webrtc::AudioMixerImpl::Create();
    config.audio_device_module =
        webrtc::test::MockAudioDeviceModule::CreateNice();
    call_config.audio_state = webrtc::AudioState::Create(config);
  }
  auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
  cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
                                           cricket::AudioOptions(),
                                           webrtc::CryptoOptions(), call.get());
  {
    cricket::AudioSendParameters params;
    params.codecs.push_back(cricket::AudioCodec(1, "opus", 48000, 32000, 2));
    params.extensions.push_back(webrtc::RtpExtension(
        webrtc::RtpExtension::kTransportSequenceNumberUri, 1));
    EXPECT_TRUE(channel.SetSendParameters(params));
  }
  constexpr int kSsrc = 1234;
  {
    cricket::StreamParams params;
    params.add_ssrc(kSsrc);
    channel.AddSendStream(params);
  }
  channel.SetAudioSend(kSsrc, true, nullptr, &source);
  channel.SetSend(true);
  webrtc::RtpParameters params = channel.GetRtpSendParameters(kSsrc);
  for (int max_bitrate : {-10, -1, 0, 10000}) {
    params.encodings[0].max_bitrate_bps = max_bitrate;
    channel.SetRtpSendParameters(
        kSsrc, params, [](webrtc::RTCError error) { EXPECT_TRUE(error.ok()); });
  }
}

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.get(), 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);
  }
}
