/*
 *  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 <memory>
#include <utility>

#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/media_transport_config.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "call/call.h"
#include "logging/rtc_event_log/rtc_event_log.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 "media/engine/webrtc_voice_engine.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
#include "test/mock_audio_encoder_factory.h"

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

namespace {
using webrtc::BitrateConstraints;

constexpr uint32_t kMaxUnsignaledRecvStreams = 4;

const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
const cricket::AudioCodec 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::NoiseSuppression::Level kDefaultNsLevel =
    webrtc::NoiseSuppression::kHigh;

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

  // Setup.
  EXPECT_CALL(*adm, AddRef()).Times(3);
  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));
  EXPECT_CALL(*adm, Release())
      .Times(3)
      .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
}
}  // namespace

// Tests that our stub library "works".
TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
      webrtc::CreateDefaultTaskQueueFactory();
  StrictMock<webrtc::test::MockAudioDeviceModule> adm;
  AdmSetupExpectations(&adm);
  rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
      new rtc::RefCountedObject<
          StrictMock<webrtc::test::MockAudioProcessing>>();
  webrtc::AudioProcessing::Config apm_config;
  EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
  EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
  EXPECT_CALL(*apm, SetExtraOptions(::testing::_));
  EXPECT_CALL(*apm, DetachAecDump());
  {
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), &adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
    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::Test {
 public:
  WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}

  explicit WebRtcVoiceEngineTestFake(const char* field_trials)
      : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
        apm_(new rtc::RefCountedObject<
             StrictMock<webrtc::test::MockAudioProcessing>>()),
        apm_ns_(*apm_->noise_suppression()),
        call_(),
        override_field_trials_(field_trials) {
    // AudioDeviceModule.
    AdmSetupExpectations(&adm_);
    // AudioProcessing.
    EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
    EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
    EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
    EXPECT_CALL(*apm_, DetachAecDump());
    // Default Options.
    EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
    EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
    // TODO(kwiberg): We should use mock factories here, but a bunch of
    // the tests here probe the specific set of codecs provided by the builtin
    // factories. Those tests should probably be moved elsewhere.
    auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
    auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
    engine_.reset(new cricket::WebRtcVoiceEngine(
        task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
        nullptr, apm_));
    engine_->Init();
    send_parameters_.codecs.push_back(kPcmuCodec);
    recv_parameters_.codecs.push_back(kPcmuCodec);

    // Default Options.
    EXPECT_TRUE(IsEchoCancellationEnabled());
    EXPECT_TRUE(IsHighPassFilterEnabled());
    EXPECT_TRUE(IsTypingDetectionEnabled());
    VerifyGainControlEnabledCorrectly();
    VerifyGainControlDefaultSettings();
  }

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

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

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

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

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

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

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

  void TearDown() override { delete channel_; }

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

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

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

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

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

  void SetSendParameters(const cricket::AudioSendParameters& params) {
    EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
    ASSERT_TRUE(channel_);
    EXPECT_TRUE(channel_->SetSendParameters(params));
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    SetSendParameters(send_parameters_);
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
    webrtc::AudioSendStream::Stats stats;
    stats.local_ssrc = 12;
    stats.bytes_sent = 345;
    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.ext_seqnum = 789;
    stats.jitter_ms = 12;
    stats.rtt_ms = 345;
    stats.audio_level = 678;
    stats.apm_statistics.delay_median_ms = 234;
    stats.apm_statistics.delay_standard_deviation_ms = 567;
    stats.apm_statistics.echo_return_loss = 890;
    stats.apm_statistics.echo_return_loss_enhancement = 1234;
    stats.apm_statistics.residual_echo_likelihood = 0.432f;
    stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
    stats.ana_statistics.bitrate_action_counter = 321;
    stats.ana_statistics.channel_action_counter = 432;
    stats.ana_statistics.dtx_action_counter = 543;
    stats.ana_statistics.fec_action_counter = 654;
    stats.ana_statistics.frame_length_increase_counter = 765;
    stats.ana_statistics.frame_length_decrease_counter = 876;
    stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
    stats.typing_noise_detected = true;
    return stats;
  }
  void SetAudioSendStreamStats() {
    for (auto* s : call_.GetAudioSendStreams()) {
      s->SetStats(GetAudioSendStreamStats());
    }
  }
  void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
                             bool is_sending) {
    const auto stats = GetAudioSendStreamStats();
    EXPECT_EQ(info.ssrc(), stats.local_ssrc);
    EXPECT_EQ(info.bytes_sent, stats.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.ext_seqnum, stats.ext_seqnum);
    EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
    EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
    EXPECT_EQ(info.audio_level, stats.audio_level);
    EXPECT_EQ(info.apm_statistics.delay_median_ms,
              stats.apm_statistics.delay_median_ms);
    EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
              stats.apm_statistics.delay_standard_deviation_ms);
    EXPECT_EQ(info.apm_statistics.echo_return_loss,
              stats.apm_statistics.echo_return_loss);
    EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
              stats.apm_statistics.echo_return_loss_enhancement);
    EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
              stats.apm_statistics.residual_echo_likelihood);
    EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
              stats.apm_statistics.residual_echo_likelihood_recent_max);
    EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
              stats.ana_statistics.bitrate_action_counter);
    EXPECT_EQ(info.ana_statistics.channel_action_counter,
              stats.ana_statistics.channel_action_counter);
    EXPECT_EQ(info.ana_statistics.dtx_action_counter,
              stats.ana_statistics.dtx_action_counter);
    EXPECT_EQ(info.ana_statistics.fec_action_counter,
              stats.ana_statistics.fec_action_counter);
    EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
              stats.ana_statistics.frame_length_increase_counter);
    EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
              stats.ana_statistics.frame_length_decrease_counter);
    EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
              stats.ana_statistics.uplink_packet_loss_fraction);
    EXPECT_EQ(info.typing_noise_detected,
              stats.typing_noise_detected && is_sending);
  }

  webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
    webrtc::AudioReceiveStream::Stats stats;
    stats.remote_ssrc = 123;
    stats.bytes_rcvd = 456;
    stats.packets_rcvd = 768;
    stats.packets_lost = 101;
    stats.codec_name = "codec_name_recv";
    stats.codec_payload_type = 42;
    stats.ext_seqnum = 678;
    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_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.bytes_rcvd, stats.bytes_rcvd);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
              stats.packets_rcvd);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
              stats.packets_lost);
    EXPECT_EQ(info.codec_name, stats.codec_name);
    EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
    EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
              stats.ext_seqnum);
    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_cng, stats.decoding_cng);
    EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
    EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
    EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
  }
  void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
    EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
    for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
      ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
      EXPECT_EQ(info.send_codecs.find(codec.id)->second,
                codec.ToCodecParameters());
    }
    EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
    for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
      ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
      EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
                codec.ToCodecParameters());
    }
  }

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

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

  bool IsEchoCancellationEnabled() {
    return apm_config_.echo_canceller.enabled;
  }

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

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

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

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

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

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

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

TEST_F(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_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
  EXPECT_TRUE(SetupChannel());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs[0].id = 106;  // collide with existing CN 32k
  parameters.codecs[2].id = 126;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}},
                   {106, {"ISAC", 16000, 1}},
                   {126, {"telephone-event", 8000, 1}},
                   {107, {"telephone-event", 32000, 1}}})));
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

TEST_F(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_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
  EXPECT_TRUE(SetupChannel());
  const int kDesiredBitrate = 128000;
  cricket::AudioSendParameters parameters;
  parameters.codecs = engine_->send_codecs();
  parameters.max_bandwidth_bps = kDesiredBitrate;
  SetSendParameters(parameters);

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

  EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
}

// Test that bitrate cannot be set for CBR codecs.
// Bitrate is ignored if it is higher than the fixed bitrate.
// Bitrate less then the fixed bitrate is an error.
TEST_F(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_F(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_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
  EXPECT_TRUE(SetupChannel());
  webrtc::RtpParameters nonexistent_parameters =
      channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(0u, nonexistent_parameters.encodings.size());

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

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

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

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

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

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

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

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

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

// RTCRtpEncodingParameters.network_priority must be one of a few values
// derived from the default priority, corresponding to very-low, low, medium,
// or high.
TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
  EXPECT_TRUE(SetupSendStream());
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            parameters.encodings[0].network_priority);

  double good_values[] = {0.5, 1.0, 2.0, 4.0};
  double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
  for (auto it : good_values) {
    parameters.encodings[0].network_priority = it;
    EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  }
  for (auto it : bad_values) {
    parameters.encodings[0].network_priority = it;
    EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

// Test that max_bitrate_bps in send stream config gets updated correctly when
// SetRtpSendParameters is called.
TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
  webrtc::test::ScopedFieldTrials override_field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/");
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters send_parameters;
  send_parameters.codecs.push_back(kOpusCodec);
  SetSendParameters(send_parameters);

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

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

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

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

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

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

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

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

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

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

// Test that GetRtpReceiveParameters returns an SSRC.
TEST_F(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_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

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

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

  // ... 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_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
  ASSERT_TRUE(SetupChannel());
  // Call necessary methods to configure receiving a default stream as
  // soon as it arrives.
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

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

  // Set a sink for an unsignaled stream.
  std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
  // Value of "0" means "unsignaled stream".
  channel_->SetRawAudioSink(0, std::move(fake_sink));

  // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
  // in this method means "unsignaled stream".
  webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
  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_->GetRtpReceiveParameters(0);
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
}

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

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

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

// Test that if clockrate is not 48000 for opus, we fail.
TEST_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
  SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
                                     200000);
}

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

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

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

TEST_F(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_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
  EXPECT_TRUE(SetupRecvStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kOpusCodec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
  SetSendParameters(parameters);
  // NACK should be enabled even with no send stream.
  EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);

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

// Test that we can enable NACK on receive streams.
TEST_F(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_F(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_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kCn16000Codec);
  parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
  SetSendParameters(parameters);

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

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

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

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

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

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

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

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

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

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

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

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

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

// Test that we fail if no codecs are specified.
TEST_F(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_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kTelephoneEventCodec1);
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  parameters.codecs[0].id = 98;  // DTMF
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
  EXPECT_EQ(96, spec.payload_type);
  EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
}

// Test that CanInsertDtmf() is governed by the send flag
TEST_F(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_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioSendParameters parameters;
  parameters.codecs.push_back(kTelephoneEventCodec2);
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs[0].id = 0;  // DTMF
  parameters.codecs[1].id = 96;
  SetSendParameters(parameters);
  SetSend(true);
  EXPECT_TRUE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = 128;  // DTMF
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
  EXPECT_FALSE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = 127;
  SetSendParameters(parameters);
  EXPECT_TRUE(channel_->CanInsertDtmf());
  parameters.codecs[0].id = -1;  // DTMF
  EXPECT_FALSE(channel_->SetSendParameters(parameters));
  EXPECT_FALSE(channel_->CanInsertDtmf());
}

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

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

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

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

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

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

class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
 public:
  WebRtcVoiceEngineWithSendSideBweTest()
      : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
};

TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
       SupportsTransportSequenceNumberHeaderExtension) {
  const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
  EXPECT_THAT(capabilities.header_extensions,
              Contains(::testing::Field(
                  "uri", &RtpExtension::uri,
                  webrtc::RtpExtension::kTransportSequenceNumberUri)));
}

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

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

// Test that we can create a channel and start sending on it.
TEST_F(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_F(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_F(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_F(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_F(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_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
  SetupForMultiSendStream();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // Check stats for the added streams.
  {
    cricket::VoiceMediaInfo info;
    EXPECT_EQ(true, channel_->GetStats(&info));

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

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

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

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

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

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

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

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

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

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

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

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

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

TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
      .Times(::testing::AtLeast(1))
      .WillRepeatedly(Return(false));
  const auto& agc_config = apm_config_.gain_controller1;

  // Ensure default options.
  VerifyGainControlEnabledCorrectly();
  VerifyGainControlDefaultSettings();

  send_parameters_.options.auto_gain_control = false;
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(agc_config.enabled);
  send_parameters_.options.auto_gain_control = absl::nullopt;

  send_parameters_.options.tx_agc_target_dbov = 5;
  SetSendParameters(send_parameters_);
  EXPECT_EQ(5, agc_config.target_level_dbfs);
  send_parameters_.options.tx_agc_target_dbov = absl::nullopt;

  send_parameters_.options.tx_agc_digital_compression_gain = 10;
  SetSendParameters(send_parameters_);
  EXPECT_EQ(10, agc_config.compression_gain_db);
  send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;

  send_parameters_.options.tx_agc_limiter = false;
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(agc_config.enable_limiter);
  send_parameters_.options.tx_agc_limiter = absl::nullopt;

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

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

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

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

TEST_F(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.
  {
    cricket::VoiceMediaInfo info;
    EXPECT_EQ(true, channel_->GetStats(&info));

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

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

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

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

// Test that we can set the outgoing SSRC properly with multiple streams.
// SSRC is set in SetupSendStream() by calling AddSendStream.
TEST_F(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_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
  EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
  EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
}

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

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

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

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

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

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

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

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

// Test that receiving on an unsignaled stream works (a stream is created).
TEST_F(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_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
  const char kSyncLabel[] = "sync_label";
  EXPECT_TRUE(SetupChannel());
  cricket::StreamParams unsignaled_stream;
  unsignaled_stream.set_stream_ids({kSyncLabel});
  ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
  // The stream shouldn't have been created at this point because it doesn't
  // have any SSRCs.
  EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());

  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));

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

  // Removing the unsignaled stream clears the cached parameters. If a new
  // default unsignaled receive stream is created it will not have a sync group.
  channel_->RemoveRecvStream(0);
  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 that receiving N unsignaled stream works (streams will be created), and
// that packets are forwarded to them all.
TEST_F(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_F(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_F(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_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
  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* recreated when a
  // stream with SSRC=1 is added, and which has changed stream parameters.
  const auto& streams = call_.GetAudioReceiveStreams();
  EXPECT_EQ(1u, streams.size());
  int audio_receive_stream_id = streams.front()->id();
  cricket::StreamParams stream_params;
  stream_params.ssrcs.push_back(1);
  stream_params.set_stream_ids({"stream_id"});
  EXPECT_TRUE(channel_->AddRecvStream(stream_params));
  EXPECT_EQ(1u, streams.size());
  EXPECT_NE(audio_receive_stream_id, streams.front()->id());
}

// Test that AddRecvStream creates new stream.
TEST_F(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_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
  EXPECT_TRUE(SetupSendStream());
  cricket::AudioRecvParameters parameters;
  parameters.codecs.push_back(kIsacCodec);
  parameters.codecs.push_back(kPcmuCodec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_TRUE(AddRecvStream(kSsrcX));
  EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
              (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
                  {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
}

// Test that we properly clean up any streams that were added, even if
// not explicitly removed.
TEST_F(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_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_FALSE(AddRecvStream(0));
}

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

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

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

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

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

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

TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_TRUE(AddRecvStream(kSsrcY));
  EXPECT_CALL(adm_, BuiltInAECIsAvailable())
      .Times(9)
      .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_);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_TRUE(IsHighPassFilterEnabled());
  EXPECT_TRUE(IsTypingDetectionEnabled());
  EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
  EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);

  // Turn typing detection off.
  send_parameters_.options.typing_detection = false;
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(IsTypingDetectionEnabled());

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

  // Turn typing detection on.
  send_parameters_.options.typing_detection = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsTypingDetectionEnabled());

  // Turn echo cancellation off
  send_parameters_.options.echo_cancellation = false;
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(IsEchoCancellationEnabled());

  // Turn echo cancellation back on, with settings, and make sure
  // nothing else changed.
  send_parameters_.options.echo_cancellation = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());

  // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
  // control.
  send_parameters_.options.delay_agnostic_aec = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());

  // Turn off echo cancellation and delay agnostic aec.
  send_parameters_.options.delay_agnostic_aec = false;
  send_parameters_.options.extended_filter_aec = false;
  send_parameters_.options.echo_cancellation = false;
  SetSendParameters(send_parameters_);
  EXPECT_FALSE(IsEchoCancellationEnabled());

  // Turning delay agnostic aec back on should also turn on echo cancellation.
  send_parameters_.options.delay_agnostic_aec = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());

  // Turn off AGC
  send_parameters_.options.auto_gain_control = false;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_FALSE(apm_config_.gain_controller1.enabled);

  // Turn AGC back on
  send_parameters_.options.auto_gain_control = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_TRUE(apm_config_.gain_controller1.enabled);

  // Turn off other options.
  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
  send_parameters_.options.noise_suppression = false;
  send_parameters_.options.highpass_filter = false;
  send_parameters_.options.stereo_swapping = true;
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_FALSE(IsHighPassFilterEnabled());
  EXPECT_TRUE(apm_config_.gain_controller1.enabled);

  // Set options again to ensure it has no impact.
  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
  SetSendParameters(send_parameters_);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_TRUE(apm_config_.gain_controller1.enabled);
}

TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
  EXPECT_TRUE(SetupSendStream());
  EXPECT_CALL(adm_, BuiltInAECIsAvailable())
      .Times(8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
      .Times(8)
      .WillRepeatedly(Return(false));
  EXPECT_CALL(adm_, BuiltInNSIsAvailable())
      .Times(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));
  EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(10);

  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_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
  EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  VerifyGainControlEnabledCorrectly();
  EXPECT_EQ(parameters_options_all.options, channel1->options());
  EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  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_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
  EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  VerifyGainControlEnabledCorrectly();
  cricket::AudioOptions expected_options = parameters_options_all.options;
  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_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
  EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_FALSE(apm_config_.gain_controller1.enabled);
  expected_options.echo_cancellation = true;
  expected_options.auto_gain_control = false;
  expected_options.noise_suppression = true;
  EXPECT_EQ(expected_options, channel2->options());

  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
  EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  VerifyGainControlEnabledCorrectly();

  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
  channel1->SetSend(true);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  VerifyGainControlEnabledCorrectly();

  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
  channel2->SetSend(true);
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_FALSE(apm_config_.gain_controller1.enabled);

  // 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_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
  EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
  EXPECT_TRUE(IsEchoCancellationEnabled());
  EXPECT_FALSE(apm_config_.gain_controller1.enabled);
  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_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
  EXPECT_TRUE(SetupSendStream());
  cricket::FakeNetworkInterface network_interface;
  cricket::MediaConfig config;
  std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
  webrtc::RtpParameters parameters;

  EXPECT_CALL(*apm_, SetExtraOptions(::testing::_)).Times(3);

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

  config.enable_dscp = true;
  channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
      engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
                                  webrtc::CryptoOptions())));
  channel->SetInterface(&network_interface, webrtc::MediaTransportConfig());
  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 = 4.0;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
  EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
  parameters.encodings[0].network_priority = 0.5;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
  EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());

  // A bad priority does not change the dscp value.
  parameters.encodings[0].network_priority = 0.0;
  ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
  EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());

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

  // 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, webrtc::MediaTransportConfig());
  // Default value when DSCP is disabled should be DSCP_DEFAULT.
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());

  channel->SetInterface(nullptr, webrtc::MediaTransportConfig());
}

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

TEST_F(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_->SetOutputVolume(kSsrc0, 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 with SSRC=0 should affect all unsignaled streams.
  EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 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_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
  EXPECT_TRUE(SetupChannel());
  EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // Set up receive extensions.
  cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
  cricket::AudioRecvParameters recv_parameters;
  recv_parameters.extensions = capabilities.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(capabilities.header_extensions.size(), s_exts.size());
    for (const auto& e_ext : capabilities.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_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
  // Test that packets are forwarded to the Call when configured accordingly.
  const uint32_t kAudioSsrc = 1;
  rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
  static const unsigned char kRtcp[] = {
      0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));

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

  EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
  const cricket::FakeAudioReceiveStream* s =
      call_.GetAudioReceiveStream(kAudioSsrc);
  EXPECT_EQ(0, s->received_packets());
  channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
  EXPECT_EQ(1, s->received_packets());
  channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
  EXPECT_EQ(2, s->received_packets());
}

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

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

TEST_F(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_F(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_->SetRawAudioSink(0, 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_->SetRawAudioSink(kSsrc0, nullptr);
  EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());

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

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

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

  // Reset the default sink - the second unsignaled stream should lose it.
  channel_->SetRawAudioSink(kSsrc0, 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_->SetRawAudioSink(kSsrc0, 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_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
  EXPECT_TRUE(SetupChannel());

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

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

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

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

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

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

// Tests when GetSources is called with non-existing ssrc, it will return an
// empty list of RtpSource without crashing.
TEST_F(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) {
  // 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();
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
  rtc::scoped_refptr<webrtc::AudioProcessing> apm =
      webrtc::AudioProcessingBuilder().Create();
  cricket::WebRtcVoiceEngine engine(
      task_queue_factory.get(), &adm,
      webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
      webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
  engine.Init();
  webrtc::RtcEventLogNullImpl event_log;
  std::unique_ptr<webrtc::Call> call(
      webrtc::Call::Create(webrtc::Call::Config(&event_log)));
  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) {
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
      webrtc::CreateDefaultTaskQueueFactory();
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
  EXPECT_CALL(adm, AddRef()).Times(3);
  EXPECT_CALL(adm, Release())
      .Times(3)
      .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
  {
    rtc::scoped_refptr<webrtc::AudioProcessing> apm =
        webrtc::AudioProcessingBuilder().Create();
    cricket::WebRtcVoiceEngine engine(
        task_queue_factory.get(), &adm,
        webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
        webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
    engine.Init();
    webrtc::RtcEventLogNullImpl event_log;
    std::unique_ptr<webrtc::Call> call(
        webrtc::Call::Create(webrtc::Call::Config(&event_log)));
    cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
        call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
        webrtc::CryptoOptions());
    EXPECT_TRUE(channel != nullptr);
    delete channel;
  }
}

// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
  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.
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
  rtc::scoped_refptr<webrtc::AudioProcessing> apm =
      webrtc::AudioProcessingBuilder().Create();
  cricket::WebRtcVoiceEngine engine(
      task_queue_factory.get(), &adm,
      webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
      webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
  engine.Init();
  for (const cricket::AudioCodec& codec : engine.send_codecs()) {
    auto is_codec = [&codec](const char* name, int clockrate = 0) {
      return absl::EqualsIgnoreCase(codec.name, name) &&
             (clockrate == 0 || codec.clockrate == clockrate);
    };
    if (is_codec("CN", 16000)) {
      EXPECT_EQ(105, codec.id);
    } else if (is_codec("CN", 32000)) {
      EXPECT_EQ(106, codec.id);
    } else if (is_codec("ISAC", 16000)) {
      EXPECT_EQ(103, codec.id);
    } else if (is_codec("ISAC", 32000)) {
      EXPECT_EQ(104, codec.id);
    } else if (is_codec("G722", 8000)) {
      EXPECT_EQ(9, codec.id);
    } else if (is_codec("telephone-event", 8000)) {
      EXPECT_EQ(126, codec.id);
      // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
      // Remove these checks once both send and receive side assigns payload
      // types dynamically.
    } else if (is_codec("telephone-event", 16000)) {
      EXPECT_EQ(113, codec.id);
    } else if (is_codec("telephone-event", 32000)) {
      EXPECT_EQ(112, codec.id);
    } else if (is_codec("telephone-event", 48000)) {
      EXPECT_EQ(110, codec.id);
    } else if (is_codec("opus")) {
      EXPECT_EQ(111, codec.id);
      ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
      EXPECT_EQ("10", codec.params.find("minptime")->second);
      ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
      EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
    }
  }
}

// Tests that VoE supports at least 32 channels
TEST(WebRtcVoiceEngineTest, Has32Channels) {
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
      webrtc::CreateDefaultTaskQueueFactory();
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
  rtc::scoped_refptr<webrtc::AudioProcessing> apm =
      webrtc::AudioProcessingBuilder().Create();
  cricket::WebRtcVoiceEngine engine(
      task_queue_factory.get(), &adm,
      webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
      webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
  engine.Init();
  webrtc::RtcEventLogNullImpl event_log;
  std::unique_ptr<webrtc::Call> call(
      webrtc::Call::Create(webrtc::Call::Config(&event_log)));

  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) {
  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.
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
  rtc::scoped_refptr<webrtc::AudioProcessing> apm =
      webrtc::AudioProcessingBuilder().Create();
  cricket::WebRtcVoiceEngine engine(
      task_queue_factory.get(), &adm,
      webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
      webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
  engine.Init();
  webrtc::RtcEventLogNullImpl event_log;
  std::unique_ptr<webrtc::Call> call(
      webrtc::Call::Create(webrtc::Call::Config(&event_log)));
  cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
                                           cricket::AudioOptions(),
                                           webrtc::CryptoOptions(), call.get());
  cricket::AudioRecvParameters parameters;
  parameters.codecs = engine.recv_codecs();
  EXPECT_TRUE(channel.SetRecvParameters(parameters));
}

TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
  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 =
      new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
  EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
      .WillOnce(Return(specs));
  ::testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;

  rtc::scoped_refptr<webrtc::AudioProcessing> apm =
      webrtc::AudioProcessingBuilder().Create();
  cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
                                    unused_encoder_factory,
                                    mock_decoder_factory, nullptr, apm);
  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);
}
