/*
 *  Copyright 2018 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.
 */

// This file contains tests for `RtpTransceiver`.

#include "pc/rtp_transceiver.h"

#include <memory>
#include <optional>
#include <utility>

#include "absl/strings/string_view.h"
#include "api/environment/environment_factory.h"
#include "api/peer_connection_interface.h"
#include "api/rtp_parameters.h"
#include "api/test/rtc_error_matchers.h"
#include "media/base/codec_comparators.h"
#include "media/base/fake_media_engine.h"
#include "pc/rtp_parameters_conversion.h"
#include "pc/test/enable_fake_media.h"
#include "pc/test/mock_channel_interface.h"
#include "pc/test/mock_rtp_receiver_internal.h"
#include "pc/test/mock_rtp_sender_internal.h"
#include "rtc_base/thread.h"
#include "test/gmock.h"
#include "test/gtest.h"

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::NiceMock;
using ::testing::Optional;
using ::testing::Property;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SizeIs;

namespace webrtc {

namespace {

class RtpTransceiverTest : public testing::Test {
 public:
  RtpTransceiverTest()
      : dependencies_(MakeDependencies()),
        context_(
            ConnectionContext::Create(CreateEnvironment(), &dependencies_)) {}

 protected:
  cricket::FakeMediaEngine* media_engine() {
    // We know this cast is safe because we supplied the fake implementation
    // in MakeDependencies().
    return static_cast<cricket::FakeMediaEngine*>(context_->media_engine());
  }
  ConnectionContext* context() { return context_.get(); }

 private:
  rtc::AutoThread main_thread_;

  static PeerConnectionFactoryDependencies MakeDependencies() {
    PeerConnectionFactoryDependencies d;
    d.network_thread = rtc::Thread::Current();
    d.worker_thread = rtc::Thread::Current();
    d.signaling_thread = rtc::Thread::Current();
    EnableFakeMedia(d, std::make_unique<cricket::FakeMediaEngine>());
    return d;
  }

  PeerConnectionFactoryDependencies dependencies_;
  rtc::scoped_refptr<ConnectionContext> context_;
};

// Checks that a channel cannot be set on a stopped `RtpTransceiver`.
TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
  const std::string content_name("my_mid");
  auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
      cricket::MediaType::MEDIA_TYPE_AUDIO, context());
  auto channel1 = std::make_unique<NiceMock<cricket::MockChannelInterface>>();
  EXPECT_CALL(*channel1, media_type())
      .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
  EXPECT_CALL(*channel1, mid()).WillRepeatedly(ReturnRef(content_name));
  EXPECT_CALL(*channel1, SetFirstPacketReceivedCallback(_));
  EXPECT_CALL(*channel1, SetRtpTransport(_)).WillRepeatedly(Return(true));
  auto channel1_ptr = channel1.get();
  transceiver->SetChannel(std::move(channel1), [&](const std::string& mid) {
    EXPECT_EQ(mid, content_name);
    return nullptr;
  });
  EXPECT_EQ(channel1_ptr, transceiver->channel());

  // Stop the transceiver.
  transceiver->StopInternal();
  EXPECT_EQ(channel1_ptr, transceiver->channel());

  auto channel2 = std::make_unique<NiceMock<cricket::MockChannelInterface>>();
  EXPECT_CALL(*channel2, media_type())
      .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));

  // Clear the current channel - required to allow SetChannel()
  EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
  transceiver->ClearChannel();
  ASSERT_EQ(nullptr, transceiver->channel());
  // Channel can no longer be set, so this call should be a no-op.
  transceiver->SetChannel(std::move(channel2),
                          [](const std::string&) { return nullptr; });
  EXPECT_EQ(nullptr, transceiver->channel());
}

// Checks that a channel can be unset on a stopped `RtpTransceiver`
TEST_F(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
  const std::string content_name("my_mid");
  auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
      cricket::MediaType::MEDIA_TYPE_VIDEO, context());
  auto channel = std::make_unique<NiceMock<cricket::MockChannelInterface>>();
  EXPECT_CALL(*channel, media_type())
      .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
  EXPECT_CALL(*channel, mid()).WillRepeatedly(ReturnRef(content_name));
  EXPECT_CALL(*channel, SetFirstPacketReceivedCallback(_))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(*channel, SetRtpTransport(_)).WillRepeatedly(Return(true));

  auto channel_ptr = channel.get();
  transceiver->SetChannel(std::move(channel), [&](const std::string& mid) {
    EXPECT_EQ(mid, content_name);
    return nullptr;
  });
  EXPECT_EQ(channel_ptr, transceiver->channel());

  // Stop the transceiver.
  transceiver->StopInternal();
  EXPECT_EQ(channel_ptr, transceiver->channel());

  // Set the channel to `nullptr`.
  transceiver->ClearChannel();
  EXPECT_EQ(nullptr, transceiver->channel());
}

class RtpTransceiverUnifiedPlanTest : public RtpTransceiverTest {
 public:
  static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver(
      cricket::MediaType media_type) {
    auto receiver = rtc::make_ref_counted<NiceMock<MockRtpReceiverInternal>>();
    EXPECT_CALL(*receiver.get(), media_type())
        .WillRepeatedly(Return(media_type));
    return receiver;
  }

  static rtc::scoped_refptr<MockRtpSenderInternal> MockSender(
      cricket::MediaType media_type) {
    auto sender = rtc::make_ref_counted<NiceMock<MockRtpSenderInternal>>();
    EXPECT_CALL(*sender.get(), media_type()).WillRepeatedly(Return(media_type));
    return sender;
  }

  rtc::scoped_refptr<RtpTransceiver> CreateTransceiver(
      rtc::scoped_refptr<RtpSenderInternal> sender,
      rtc::scoped_refptr<RtpReceiverInternal> receiver) {
    return rtc::make_ref_counted<RtpTransceiver>(
        RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
            rtc::Thread::Current(), std::move(sender)),
        RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
            rtc::Thread::Current(), rtc::Thread::Current(),
            std::move(receiver)),
        context(), media_engine()->voice().GetRtpHeaderExtensions(),
        /* on_negotiation_needed= */ [] {});
  }

 protected:
  rtc::AutoThread main_thread_;
};

// Basic tests for Stop()
TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
  rtc::scoped_refptr<MockRtpReceiverInternal> receiver =
      MockReceiver(cricket::MediaType::MEDIA_TYPE_AUDIO);
  rtc::scoped_refptr<MockRtpSenderInternal> sender =
      MockSender(cricket::MediaType::MEDIA_TYPE_AUDIO);
  rtc::scoped_refptr<RtpTransceiver> transceiver =
      CreateTransceiver(sender, receiver);

  EXPECT_CALL(*receiver.get(), Stop());
  EXPECT_CALL(*receiver.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender.get(), Stop());

  EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver->direction());
  EXPECT_FALSE(transceiver->current_direction());
  transceiver->StopStandard();
  EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver->direction());
  EXPECT_FALSE(transceiver->current_direction());
  transceiver->StopTransceiverProcedure();
  EXPECT_TRUE(transceiver->current_direction());
  EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver->direction());
  EXPECT_EQ(RtpTransceiverDirection::kStopped,
            *transceiver->current_direction());
}

class RtpTransceiverFilteredCodecPreferencesTest
    : public RtpTransceiverUnifiedPlanTest {
 public:
  RtpTransceiverFilteredCodecPreferencesTest()
      : transceiver_(CreateTransceiver(
            MockSender(cricket::MediaType::MEDIA_TYPE_VIDEO),
            MockReceiver(cricket::MediaType::MEDIA_TYPE_VIDEO))) {}

  struct H264CodecCapabilities {
    cricket::Codec cricket_sendrecv_codec;
    RtpCodecCapability sendrecv_codec;
    cricket::Codec cricket_sendonly_codec;
    RtpCodecCapability sendonly_codec;
    cricket::Codec cricket_recvonly_codec;
    RtpCodecCapability recvonly_codec;
    cricket::Codec cricket_rtx_codec;
    RtpCodecCapability rtx_codec;
  };

  // For H264, the profile and level IDs are entangled. This function uses
  // profile-level-id values that are not equal even when levels are ignored.
  H264CodecCapabilities ConfigureH264CodecCapabilities() {
    cricket::Codec cricket_sendrecv_codec = cricket::CreateVideoCodec(
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "42f00b"}},
                       {ScalabilityMode::kL1T1}));
    cricket::Codec cricket_sendonly_codec = cricket::CreateVideoCodec(
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "640034"}},
                       {ScalabilityMode::kL1T1}));
    cricket::Codec cricket_recvonly_codec = cricket::CreateVideoCodec(
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "f4001f"}},
                       {ScalabilityMode::kL1T1}));
    cricket::Codec cricket_rtx_codec = cricket::CreateVideoRtxCodec(
        cricket::Codec::kIdNotSet, cricket::Codec::kIdNotSet);
    media_engine()->SetVideoSendCodecs(
        {cricket_sendrecv_codec, cricket_sendonly_codec, cricket_rtx_codec});
    media_engine()->SetVideoRecvCodecs(
        {cricket_sendrecv_codec, cricket_recvonly_codec, cricket_rtx_codec});
    H264CodecCapabilities capabilities = {
        .cricket_sendrecv_codec = cricket_sendrecv_codec,
        .sendrecv_codec = ToRtpCodecCapability(cricket_sendrecv_codec),
        .cricket_sendonly_codec = cricket_sendonly_codec,
        .sendonly_codec = ToRtpCodecCapability(cricket_sendonly_codec),
        .cricket_recvonly_codec = cricket_recvonly_codec,
        .recvonly_codec = ToRtpCodecCapability(cricket_recvonly_codec),
        .cricket_rtx_codec = cricket_rtx_codec,
        .rtx_codec = ToRtpCodecCapability(cricket_rtx_codec),
    };
    EXPECT_FALSE(IsSameRtpCodecIgnoringLevel(
        capabilities.cricket_sendrecv_codec, capabilities.sendonly_codec));
    EXPECT_FALSE(IsSameRtpCodecIgnoringLevel(
        capabilities.cricket_sendrecv_codec, capabilities.recvonly_codec));
    EXPECT_FALSE(IsSameRtpCodecIgnoringLevel(
        capabilities.cricket_sendonly_codec, capabilities.recvonly_codec));
    return capabilities;
  }

#ifdef RTC_ENABLE_H265
  struct H265CodecCapabilities {
    // The level-id from sender getCapabilities() or receiver getCapabilities().
    static constexpr const char* kSendOnlyLevel = "180";
    static constexpr const char* kRecvOnlyLevel = "156";
    // A valid H265 level-id, but one not present in either getCapabilities().
    static constexpr const char* kLevelNotInCapabilities = "135";

    cricket::Codec cricket_sendonly_codec;
    RtpCodecCapability sendonly_codec;
    cricket::Codec cricket_recvonly_codec;
    RtpCodecCapability recvonly_codec;
  };

  // For H265, the profile and level IDs are separate and are ignored by
  // IsSameRtpCodecIgnoringLevel().
  H265CodecCapabilities ConfigureH265CodecCapabilities() {
    cricket::Codec cricket_sendonly_codec = cricket::CreateVideoCodec(
        SdpVideoFormat("H265",
                       {{"profile-id", "1"},
                        {"tier-flag", "0"},
                        {"level-id", H265CodecCapabilities::kSendOnlyLevel},
                        {"tx-mode", "SRST"}},
                       {ScalabilityMode::kL1T1}));
    cricket::Codec cricket_recvonly_codec = cricket::CreateVideoCodec(
        SdpVideoFormat("H265",
                       {{"profile-id", "1"},
                        {"tier-flag", "0"},
                        {"level-id", H265CodecCapabilities::kRecvOnlyLevel},
                        {"tx-mode", "SRST"}},
                       {ScalabilityMode::kL1T1}));
    media_engine()->SetVideoSendCodecs({cricket_sendonly_codec});
    media_engine()->SetVideoRecvCodecs({cricket_recvonly_codec});
    return {
        .cricket_sendonly_codec = cricket_sendonly_codec,
        .sendonly_codec = ToRtpCodecCapability(cricket_sendonly_codec),
        .cricket_recvonly_codec = cricket_recvonly_codec,
        .recvonly_codec = ToRtpCodecCapability(cricket_recvonly_codec),
    };
  }
#endif  // RTC_ENABLE_H265

 protected:
  rtc::scoped_refptr<RtpTransceiver> transceiver_;
};

TEST_F(RtpTransceiverFilteredCodecPreferencesTest, EmptyByDefault) {
  ConfigureH264CodecCapabilities();

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kInactive),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest, OrderIsMaintained) {
  const auto codecs = ConfigureH264CodecCapabilities();
  std::vector<RtpCodecCapability> codec_capabilities = {codecs.sendrecv_codec,
                                                        codecs.rtx_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0], codec_capabilities[1]));
  // Reverse order.
  codec_capabilities = {codecs.rtx_codec, codecs.sendrecv_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0], codec_capabilities[1]));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       FiltersCodecsBasedOnDirection) {
  const auto codecs = ConfigureH264CodecCapabilities();
  std::vector<RtpCodecCapability> codec_capabilities = {
      codecs.sendonly_codec, codecs.sendrecv_codec, codecs.recvonly_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.sendrecv_codec));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.sendonly_codec, codecs.sendrecv_codec));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.sendrecv_codec, codecs.recvonly_codec));

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kInactive),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.sendrecv_codec));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       RtxIsIncludedAfterFiltering) {
  const auto codecs = ConfigureH264CodecCapabilities();
  std::vector<RtpCodecCapability> codec_capabilities = {codecs.recvonly_codec,
                                                        codecs.rtx_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.recvonly_codec, codecs.rtx_codec));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       NoMediaIsTheSameAsNoPreference) {
  const auto codecs = ConfigureH264CodecCapabilities();
  std::vector<RtpCodecCapability> codec_capabilities = {codecs.recvonly_codec,
                                                        codecs.rtx_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());

  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  // After filtering the only codec that remains is RTX which is not a media
  // codec, this is the same as not having any preferences.
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));

  // But the preferences are remembered in case the direction changes such that
  // we do have a media codec.
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codecs.recvonly_codec, codecs.rtx_codec));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       H264LevelIdsIgnoredByFilter) {
  // Baseline 3.1 and 5.2 are compatible when ignoring level IDs.
  cricket::Codec baseline_3_1 = cricket::CreateVideoCodec(
      SdpVideoFormat("H264",
                     {{"level-asymmetry-allowed", "1"},
                      {"packetization-mode", "1"},
                      {"profile-level-id", "42001f"}},
                     {ScalabilityMode::kL1T1}));
  cricket::Codec baseline_5_2 = cricket::CreateVideoCodec(
      SdpVideoFormat("H264",
                     {{"level-asymmetry-allowed", "1"},
                      {"packetization-mode", "1"},
                      {"profile-level-id", "420034"}},
                     {ScalabilityMode::kL1T1}));
  // High is NOT compatible with baseline.
  cricket::Codec high_3_1 = cricket::CreateVideoCodec(
      SdpVideoFormat("H264",
                     {{"level-asymmetry-allowed", "1"},
                      {"packetization-mode", "1"},
                      {"profile-level-id", "64001f"}},
                     {ScalabilityMode::kL1T1}));
  // Configure being able to both send and receive Baseline but using different
  // level IDs in either direction, while the High profile is "truly" recvonly.
  media_engine()->SetVideoSendCodecs({baseline_3_1});
  media_engine()->SetVideoRecvCodecs({baseline_5_2, high_3_1});

  // Prefer to "sendrecv" Baseline 5.2. Even though we can only send 3.1 this
  // codec is not filtered out due to 5.2 and 3.1 being compatible when ignoring
  // level IDs.
  std::vector<RtpCodecCapability> codec_capabilities = {
      ToRtpCodecCapability(baseline_5_2)};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0]));
  // Prefer to "sendrecv" High 3.1. This gets filtered out because we cannot
  // send it (Baseline 3.1 is not compatible with it).
  codec_capabilities = {ToRtpCodecCapability(high_3_1)};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(), SizeIs(0));
  // Change direction to "recvonly" to avoid High 3.1 being filtered out.
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0]));
}

#ifdef RTC_ENABLE_H265
TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       H265LevelIdIsIgnoredByFilter) {
  const auto codecs = ConfigureH265CodecCapabilities();
  std::vector<RtpCodecCapability> codec_capabilities = {codecs.sendonly_codec,
                                                        codecs.recvonly_codec};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities), IsRtcOk());
  // Regardless of direction, both codecs are preferred due to ignoring levels.
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0], codec_capabilities[1]));
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0], codec_capabilities[1]));
  EXPECT_THAT(
      transceiver_->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  EXPECT_THAT(transceiver_->filtered_codec_preferences(),
              ElementsAre(codec_capabilities[0], codec_capabilities[1]));
}

TEST_F(RtpTransceiverFilteredCodecPreferencesTest,
       H265LevelIdHasToBeFromSenderOrReceiverCapabilities) {
  ConfigureH265CodecCapabilities();
  cricket::Codec cricket_codec = cricket::CreateVideoCodec(SdpVideoFormat(
      "H265",
      {{"profile-id", "1"},
       {"tier-flag", "0"},
       {"level-id", H265CodecCapabilities::kLevelNotInCapabilities},
       {"tx-mode", "SRST"}},
      {ScalabilityMode::kL1T1}));

  std::vector<RtpCodecCapability> codec_capabilities = {
      ToRtpCodecCapability(cricket_codec)};
  EXPECT_THAT(transceiver_->SetCodecPreferences(codec_capabilities),
              IsRtcErrorWithTypeAndMessage(
                  RTCErrorType::INVALID_MODIFICATION,
                  "Invalid codec preferences: Missing codec from codec "
                  "capabilities."));
}
#endif  // RTC_ENABLE_H265

class RtpTransceiverTestForHeaderExtensions
    : public RtpTransceiverUnifiedPlanTest {
 public:
  RtpTransceiverTestForHeaderExtensions()
      : extensions_(
            {RtpHeaderExtensionCapability("uri1",
                                          1,
                                          RtpTransceiverDirection::kSendOnly),
             RtpHeaderExtensionCapability("uri2",
                                          2,
                                          RtpTransceiverDirection::kRecvOnly),
             RtpHeaderExtensionCapability(RtpExtension::kMidUri,
                                          3,
                                          RtpTransceiverDirection::kSendRecv),
             RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri,
                                          4,
                                          RtpTransceiverDirection::kSendRecv)}),
        transceiver_(rtc::make_ref_counted<RtpTransceiver>(
            RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
                rtc::Thread::Current(),
                sender_),
            RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
                rtc::Thread::Current(),
                rtc::Thread::Current(),
                receiver_),
            context(),
            extensions_,
            /* on_negotiation_needed= */ [] {})) {}

  void ClearChannel() {
    EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
    transceiver_->ClearChannel();
  }

  rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ =
      MockReceiver(cricket::MediaType::MEDIA_TYPE_AUDIO);
  rtc::scoped_refptr<MockRtpSenderInternal> sender_ =
      MockSender(cricket::MediaType::MEDIA_TYPE_AUDIO);

  std::vector<RtpHeaderExtensionCapability> extensions_;
  rtc::scoped_refptr<RtpTransceiver> transceiver_;
};

TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto modified_extensions = extensions_;
  modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly;
  EXPECT_TRUE(
      transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(),
            modified_extensions);
  modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly;
  EXPECT_TRUE(
      transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(),
            modified_extensions);
  modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
  EXPECT_TRUE(
      transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(),
            modified_extensions);
  modified_extensions[0].direction = RtpTransceiverDirection::kInactive;
  EXPECT_TRUE(
      transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(),
            modified_extensions);
}

TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto modified_extensions = extensions_;
  modified_extensions[0].direction = RtpTransceiverDirection::kStopped;
  EXPECT_TRUE(
      transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(),
            modified_extensions);
}

TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsDifferentSize) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto modified_extensions = extensions_;
  modified_extensions.pop_back();

  EXPECT_THAT(transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions),
              Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsChangedUri) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto modified_extensions = extensions_;
  ASSERT_TRUE(!modified_extensions.empty());
  modified_extensions[0].uri = "http://webrtc.org";

  EXPECT_THAT(transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions),
              Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsReorder) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto modified_extensions = extensions_;
  ASSERT_GE(modified_extensions.size(), 2u);
  std::swap(modified_extensions[0], modified_extensions[1]);

  EXPECT_THAT(transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions),
              Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_F(RtpTransceiverTestForHeaderExtensions,
       RejectsStoppedMandatoryExtensions) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  std::vector<RtpHeaderExtensionCapability> modified_extensions = extensions_;
  // Attempting to stop the mandatory MID extension.
  modified_extensions[2].direction = RtpTransceiverDirection::kStopped;
  EXPECT_THAT(transceiver_->SetHeaderExtensionsToNegotiate(modified_extensions),
              Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
  EXPECT_EQ(transceiver_->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_F(RtpTransceiverTestForHeaderExtensions,
       NoNegotiatedHdrExtsWithoutChannel) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());
  EXPECT_THAT(transceiver_->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));
}

TEST_F(RtpTransceiverTestForHeaderExtensions,
       NoNegotiatedHdrExtsWithChannelWithoutNegotiation) {
  const std::string content_name("my_mid");
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
  EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
  EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());
  auto mock_channel =
      std::make_unique<NiceMock<cricket::MockChannelInterface>>();
  auto mock_channel_ptr = mock_channel.get();
  EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
  EXPECT_CALL(*mock_channel, media_type())
      .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
  EXPECT_CALL(*mock_channel, voice_media_send_channel())
      .WillRepeatedly(Return(nullptr));
  EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
  EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
  transceiver_->SetChannel(std::move(mock_channel),
                           [](const std::string&) { return nullptr; });
  EXPECT_THAT(transceiver_->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));

  EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
  ClearChannel();
}

TEST_F(RtpTransceiverTestForHeaderExtensions, ReturnsNegotiatedHdrExts) {
  const std::string content_name("my_mid");
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
  EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
  EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  auto mock_channel =
      std::make_unique<NiceMock<cricket::MockChannelInterface>>();
  auto mock_channel_ptr = mock_channel.get();
  EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
  EXPECT_CALL(*mock_channel, media_type())
      .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
  EXPECT_CALL(*mock_channel, voice_media_send_channel())
      .WillRepeatedly(Return(nullptr));
  EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
  EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));

  cricket::RtpHeaderExtensions extensions = {RtpExtension("uri1", 1),
                                             RtpExtension("uri2", 2)};
  cricket::AudioContentDescription description;
  description.set_rtp_header_extensions(extensions);
  transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);

  transceiver_->SetChannel(std::move(mock_channel),
                           [](const std::string&) { return nullptr; });

  EXPECT_THAT(transceiver_->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));
  EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
  ClearChannel();
}

TEST_F(RtpTransceiverTestForHeaderExtensions,
       ReturnsNegotiatedHdrExtsSecondTime) {
  EXPECT_CALL(*receiver_.get(), Stop());
  EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
  EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
  EXPECT_CALL(*sender_.get(), Stop());

  cricket::RtpHeaderExtensions extensions = {RtpExtension("uri1", 1),
                                             RtpExtension("uri2", 2)};
  cricket::AudioContentDescription description;
  description.set_rtp_header_extensions(extensions);
  transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);

  EXPECT_THAT(transceiver_->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));
  extensions = {RtpExtension("uri3", 4), RtpExtension("uri5", 6)};
  description.set_rtp_header_extensions(extensions);
  transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);

  EXPECT_THAT(transceiver_->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));
}

TEST_F(RtpTransceiverTestForHeaderExtensions,
       SimulcastOrSvcEnablesExtensionsByDefault) {
  std::vector<RtpHeaderExtensionCapability> extensions = {
      {RtpExtension::kDependencyDescriptorUri, 1,
       RtpTransceiverDirection::kStopped},
      {RtpExtension::kVideoLayersAllocationUri, 2,
       RtpTransceiverDirection::kStopped},
  };

  // Default is stopped.
  auto sender = rtc::make_ref_counted<NiceMock<MockRtpSenderInternal>>();
  auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
      RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
          rtc::Thread::Current(), sender),
      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
          rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
      context(), extensions,
      /* on_negotiation_needed= */ [] {});
  std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions =
      transceiver->GetHeaderExtensionsToNegotiate();
  ASSERT_EQ(header_extensions.size(), 2u);
  EXPECT_EQ(header_extensions[0].uri, RtpExtension::kDependencyDescriptorUri);
  EXPECT_EQ(header_extensions[0].direction, RtpTransceiverDirection::kStopped);
  EXPECT_EQ(header_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri);
  EXPECT_EQ(header_extensions[1].direction, RtpTransceiverDirection::kStopped);

  // Simulcast, i.e. more than one encoding.
  RtpParameters simulcast_parameters;
  simulcast_parameters.encodings.resize(2);
  auto simulcast_sender =
      rtc::make_ref_counted<NiceMock<MockRtpSenderInternal>>();
  EXPECT_CALL(*simulcast_sender, GetParametersInternal())
      .WillRepeatedly(Return(simulcast_parameters));
  auto simulcast_transceiver = rtc::make_ref_counted<RtpTransceiver>(
      RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
          rtc::Thread::Current(), simulcast_sender),
      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
          rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
      context(), extensions,
      /* on_negotiation_needed= */ [] {});
  auto simulcast_extensions =
      simulcast_transceiver->GetHeaderExtensionsToNegotiate();
  ASSERT_EQ(simulcast_extensions.size(), 2u);
  EXPECT_EQ(simulcast_extensions[0].uri,
            RtpExtension::kDependencyDescriptorUri);
  EXPECT_EQ(simulcast_extensions[0].direction,
            RtpTransceiverDirection::kSendRecv);
  EXPECT_EQ(simulcast_extensions[1].uri,
            RtpExtension::kVideoLayersAllocationUri);
  EXPECT_EQ(simulcast_extensions[1].direction,
            RtpTransceiverDirection::kSendRecv);

  // SVC, a single encoding with a scalabilityMode other than L1T1.
  webrtc::RtpParameters svc_parameters;
  svc_parameters.encodings.resize(1);
  svc_parameters.encodings[0].scalability_mode = "L3T3";

  auto svc_sender = rtc::make_ref_counted<NiceMock<MockRtpSenderInternal>>();
  EXPECT_CALL(*svc_sender, GetParametersInternal())
      .WillRepeatedly(Return(svc_parameters));
  auto svc_transceiver = rtc::make_ref_counted<RtpTransceiver>(
      RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
          rtc::Thread::Current(), svc_sender),
      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
          rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
      context(), extensions,
      /* on_negotiation_needed= */ [] {});
  std::vector<webrtc::RtpHeaderExtensionCapability> svc_extensions =
      svc_transceiver->GetHeaderExtensionsToNegotiate();
  ASSERT_EQ(svc_extensions.size(), 2u);
  EXPECT_EQ(svc_extensions[0].uri, RtpExtension::kDependencyDescriptorUri);
  EXPECT_EQ(svc_extensions[0].direction, RtpTransceiverDirection::kSendRecv);
  EXPECT_EQ(svc_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri);
  EXPECT_EQ(svc_extensions[1].direction, RtpTransceiverDirection::kSendRecv);
}

}  // namespace

}  // namespace webrtc
