/*
 *  Copyright 2017 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 that check the interaction between the
// PeerConnection and the underlying media engine, as well as tests that check
// the media-related aspects of SDP.

#include <algorithm>
#include <functional>
#include <iterator>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/types/optional.h"
#include "api/audio_options.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtc_event_log/rtc_event_log_factory.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_direction.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/task_queue/task_queue_factory.h"
#include "media/base/codec.h"
#include "media/base/fake_media_engine.h"
#include "media/base/media_channel.h"
#include "media/base/media_constants.h"
#include "media/base/media_engine.h"
#include "media/base/stream_params.h"
#include "p2p/base/fake_port_allocator.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/transport_info.h"
#include "pc/channel_interface.h"
#include "pc/media_session.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/rtp_media_utils.h"
#include "pc/rtp_transceiver.h"
#include "pc/session_description.h"
#include "pc/test/enable_fake_media.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/checks.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/thread.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"
#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif
#include "rtc_base/virtual_socket_server.h"
#include "test/gmock.h"

namespace webrtc {

using cricket::FakeMediaEngine;
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
using ::testing::Bool;
using ::testing::Combine;
using ::testing::ElementsAre;
using ::testing::HasSubstr;
using ::testing::NotNull;
using ::testing::Values;

cricket::MediaSendChannelInterface* SendChannelInternal(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  auto transceiver_with_internal = static_cast<
      rtc::RefCountedObject<RtpTransceiverProxyWithInternal<RtpTransceiver>>*>(
      transceiver.get());
  auto transceiver_internal =
      static_cast<RtpTransceiver*>(transceiver_with_internal->internal());
  return transceiver_internal->channel()->media_send_channel();
}

cricket::MediaReceiveChannelInterface* ReceiveChannelInternal(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  auto transceiver_with_internal = static_cast<
      rtc::RefCountedObject<RtpTransceiverProxyWithInternal<RtpTransceiver>>*>(
      transceiver.get());
  auto transceiver_internal =
      static_cast<RtpTransceiver*>(transceiver_with_internal->internal());
  return transceiver_internal->channel()->media_receive_channel();
}

cricket::FakeVideoMediaSendChannel* VideoMediaSendChannel(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  return static_cast<cricket::FakeVideoMediaSendChannel*>(
      SendChannelInternal(transceiver));
}
cricket::FakeVideoMediaReceiveChannel* VideoMediaReceiveChannel(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  return static_cast<cricket::FakeVideoMediaReceiveChannel*>(
      ReceiveChannelInternal(transceiver));
}
cricket::FakeVoiceMediaSendChannel* VoiceMediaSendChannel(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  return static_cast<cricket::FakeVoiceMediaSendChannel*>(
      SendChannelInternal(transceiver));
}
cricket::FakeVoiceMediaReceiveChannel* VoiceMediaReceiveChannel(
    rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
  return static_cast<cricket::FakeVoiceMediaReceiveChannel*>(
      ReceiveChannelInternal(transceiver));
}

class PeerConnectionWrapperForMediaTest : public PeerConnectionWrapper {
 public:
  using PeerConnectionWrapper::PeerConnectionWrapper;

  FakeMediaEngine* media_engine() { return media_engine_; }
  void set_media_engine(FakeMediaEngine* media_engine) {
    media_engine_ = media_engine;
  }

 private:
  FakeMediaEngine* media_engine_;
};

class PeerConnectionMediaBaseTest : public ::testing::Test {
 protected:
  typedef std::unique_ptr<PeerConnectionWrapperForMediaTest> WrapperPtr;

  explicit PeerConnectionMediaBaseTest(SdpSemantics sdp_semantics)
      : vss_(new rtc::VirtualSocketServer()),
        main_(vss_.get()),
        sdp_semantics_(sdp_semantics) {
#ifdef WEBRTC_ANDROID
    InitializeAndroidObjects();
#endif
  }

  WrapperPtr CreatePeerConnection() {
    return CreatePeerConnection(RTCConfiguration());
  }

  WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
    return CreatePeerConnection(config, std::make_unique<FakeMediaEngine>());
  }

  WrapperPtr CreatePeerConnection(
      std::unique_ptr<FakeMediaEngine> media_engine) {
    return CreatePeerConnection(RTCConfiguration(), std::move(media_engine));
  }

  // Creates PeerConnectionFactory and PeerConnection for given configuration.
  WrapperPtr CreatePeerConnection(
      const RTCConfiguration& config,
      std::unique_ptr<FakeMediaEngine> media_engine) {
    auto* media_engine_ptr = media_engine.get();

    PeerConnectionFactoryDependencies factory_dependencies;

    factory_dependencies.network_thread = rtc::Thread::Current();
    factory_dependencies.worker_thread = rtc::Thread::Current();
    factory_dependencies.signaling_thread = rtc::Thread::Current();
    factory_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
    EnableFakeMedia(factory_dependencies, std::move(media_engine));
    factory_dependencies.event_log_factory =
        std::make_unique<RtcEventLogFactory>();
    factory_dependencies.trials = std::move(field_trials_);
    auto pc_factory =
        CreateModularPeerConnectionFactory(std::move(factory_dependencies));

    auto fake_port_allocator = std::make_unique<cricket::FakePortAllocator>(
        rtc::Thread::Current(),
        std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()), nullptr);
    auto observer = std::make_unique<MockPeerConnectionObserver>();
    auto modified_config = config;
    modified_config.sdp_semantics = sdp_semantics_;
    PeerConnectionDependencies pc_dependencies(observer.get());
    pc_dependencies.allocator = std::move(fake_port_allocator);

    auto result = pc_factory->CreatePeerConnectionOrError(
        modified_config, std::move(pc_dependencies));
    if (!result.ok()) {
      return nullptr;
    }

    auto pc = result.MoveValue();
    observer->SetPeerConnectionInterface(pc.get());
    auto wrapper = std::make_unique<PeerConnectionWrapperForMediaTest>(
        pc_factory, pc, std::move(observer));
    wrapper->set_media_engine(media_engine_ptr);
    return wrapper;
  }

  // Accepts the same arguments as CreatePeerConnection and adds default audio
  // track (but no video).
  template <typename... Args>
  WrapperPtr CreatePeerConnectionWithAudio(Args&&... args) {
    auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
    if (!wrapper) {
      return nullptr;
    }
    wrapper->AddAudioTrack("a");
    return wrapper;
  }

  // Accepts the same arguments as CreatePeerConnection and adds default video
  // track (but no audio).
  template <typename... Args>
  WrapperPtr CreatePeerConnectionWithVideo(Args&&... args) {
    auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
    if (!wrapper) {
      return nullptr;
    }
    wrapper->AddVideoTrack("v");
    return wrapper;
  }

  // Accepts the same arguments as CreatePeerConnection and adds default audio
  // and video tracks.
  template <typename... Args>
  WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
    auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
    if (!wrapper) {
      return nullptr;
    }
    wrapper->AddAudioTrack("a");
    wrapper->AddVideoTrack("v");
    return wrapper;
  }

  RtpTransceiverDirection GetMediaContentDirection(
      const SessionDescriptionInterface* sdesc,
      cricket::MediaType media_type) {
    auto* content =
        cricket::GetFirstMediaContent(sdesc->description(), media_type);
    RTC_DCHECK(content);
    return content->media_description()->direction();
  }

  bool IsUnifiedPlan() const {
    return sdp_semantics_ == SdpSemantics::kUnifiedPlan;
  }

  std::unique_ptr<test::ScopedKeyValueConfig> field_trials_;
  std::unique_ptr<rtc::VirtualSocketServer> vss_;
  rtc::AutoSocketServerThread main_;
  const SdpSemantics sdp_semantics_;
};

class PeerConnectionMediaTest
    : public PeerConnectionMediaBaseTest,
      public ::testing::WithParamInterface<SdpSemantics> {
 protected:
  PeerConnectionMediaTest() : PeerConnectionMediaBaseTest(GetParam()) {}
};

class PeerConnectionMediaTestUnifiedPlan : public PeerConnectionMediaBaseTest {
 protected:
  PeerConnectionMediaTestUnifiedPlan()
      : PeerConnectionMediaBaseTest(SdpSemantics::kUnifiedPlan) {}
};

class PeerConnectionMediaTestPlanB : public PeerConnectionMediaBaseTest {
 protected:
  PeerConnectionMediaTestPlanB()
      : PeerConnectionMediaBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
};

TEST_P(PeerConnectionMediaTest,
       FailToSetRemoteDescriptionIfCreateMediaChannelFails) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();
  callee->media_engine()->set_fail_create_channel(true);

  std::string error;
  ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer(), &error));
  EXPECT_THAT(error,
              HasSubstr("Failed to set remote offer sdp: Failed to create"));
}

TEST_P(PeerConnectionMediaTest,
       FailToSetLocalDescriptionIfCreateMediaChannelFails) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  caller->media_engine()->set_fail_create_channel(true);

  std::string error;
  ASSERT_FALSE(caller->SetLocalDescription(caller->CreateOffer(), &error));
  EXPECT_THAT(error,
              HasSubstr("Failed to set local offer sdp: Failed to create"));
}

std::vector<std::string> GetIds(
    const std::vector<cricket::StreamParams>& streams) {
  std::vector<std::string> ids;
  ids.reserve(streams.size());
  for (const auto& stream : streams) {
    ids.push_back(stream.id);
  }
  return ids;
}

// Test that exchanging an offer and answer with each side having an audio and
// video stream creates the appropriate send/recv streams in the underlying
// media engine on both sides.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       AudioVideoOfferAnswerCreateSendRecvStreams) {
  const std::string kCallerAudioId = "caller_a";
  const std::string kCallerVideoId = "caller_v";
  const std::string kCalleeAudioId = "callee_a";
  const std::string kCalleeVideoId = "callee_v";

  auto caller = CreatePeerConnection();
  caller->AddAudioTrack(kCallerAudioId);
  caller->AddVideoTrack(kCallerVideoId);

  auto callee = CreatePeerConnection();
  callee->AddAudioTrack(kCalleeAudioId);
  callee->AddVideoTrack(kCalleeVideoId);

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  auto* caller_voice_send =
      VoiceMediaSendChannel(caller->pc()->GetTransceivers()[0]);
  auto* caller_voice_receive =
      VoiceMediaReceiveChannel(caller->pc()->GetTransceivers()[0]);
  EXPECT_THAT(GetIds(caller_voice_receive->recv_streams()),
              ElementsAre(kCalleeAudioId));
  EXPECT_THAT(GetIds(caller_voice_send->send_streams()),
              ElementsAre(kCallerAudioId));

  auto* caller_video_send =
      VideoMediaSendChannel(caller->pc()->GetTransceivers()[1]);
  auto* caller_video_receive =
      VideoMediaReceiveChannel(caller->pc()->GetTransceivers()[1]);
  EXPECT_THAT(GetIds(caller_video_receive->recv_streams()),
              ElementsAre(kCalleeVideoId));
  EXPECT_THAT(GetIds(caller_video_send->send_streams()),
              ElementsAre(kCallerVideoId));

  auto* callee_voice_send =
      VoiceMediaSendChannel(callee->pc()->GetTransceivers()[0]);
  auto* callee_voice_receive =
      VoiceMediaReceiveChannel(callee->pc()->GetTransceivers()[0]);
  EXPECT_THAT(GetIds(callee_voice_receive->recv_streams()),
              ElementsAre(kCallerAudioId));
  EXPECT_THAT(GetIds(callee_voice_send->send_streams()),
              ElementsAre(kCalleeAudioId));

  auto* callee_video_send =
      VideoMediaSendChannel(callee->pc()->GetTransceivers()[1]);
  auto* callee_video_receive =
      VideoMediaReceiveChannel(callee->pc()->GetTransceivers()[1]);
  EXPECT_THAT(GetIds(callee_video_receive->recv_streams()),
              ElementsAre(kCallerVideoId));
  EXPECT_THAT(GetIds(callee_video_send->send_streams()),
              ElementsAre(kCalleeVideoId));
}

// Test that stopping the caller transceivers causes the media channels on the
// callee to be destroyed after calling SetRemoteDescription on the generated
// offer.
// See next test for equivalent behavior with Plan B semantics.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       StoppedRemoteTransceiversRemovesMediaChannels) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  // Stop both audio and video transceivers on the caller.
  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  transceivers[0]->StopInternal();
  transceivers[1]->StopInternal();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  ASSERT_TRUE(callee->pc()->GetTransceivers().empty());
}

// Test that removing streams from a subsequent offer causes the receive streams
// on the callee to be removed.
// See previous test for equivalent behavior with Unified Plan semantics.
TEST_F(PeerConnectionMediaTestPlanB, EmptyRemoteOfferRemovesRecvStreams) {
  auto caller = CreatePeerConnection();
  auto caller_audio_track = caller->AddAudioTrack("a");
  auto caller_video_track = caller->AddVideoTrack("v");
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  // Remove both tracks from caller.
  caller->pc()->RemoveTrackOrError(caller_audio_track);
  caller->pc()->RemoveTrackOrError(caller_video_track);

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  EXPECT_TRUE(callee->pc()->GetReceivers().empty());
  EXPECT_EQ(2u, callee->pc()->GetSenders().size());
}

// Test enabling of simulcast with Plan B semantics.
// This test creating an offer.
TEST_F(PeerConnectionMediaTestPlanB, SimulcastOffer) {
  auto caller = CreatePeerConnection();
  auto caller_video_track = caller->AddVideoTrack("v");
  RTCOfferAnswerOptions options;
  options.num_simulcast_layers = 3;
  auto offer = caller->CreateOffer(options);
  auto* description = cricket::GetFirstMediaContent(offer->description(),
                                                    cricket::MEDIA_TYPE_VIDEO)
                          ->media_description();
  ASSERT_EQ(1u, description->streams().size());
  ASSERT_TRUE(description->streams()[0].get_ssrc_group("SIM"));
  EXPECT_EQ(3u, description->streams()[0].get_ssrc_group("SIM")->ssrcs.size());

  // Check that it actually creates simulcast aswell.
  caller->SetLocalDescription(std::move(offer));
  auto senders = caller->pc()->GetSenders();
  ASSERT_EQ(1u, senders.size());
  EXPECT_EQ(cricket::MediaType::MEDIA_TYPE_VIDEO, senders[0]->media_type());
  EXPECT_EQ(3u, senders[0]->GetParameters().encodings.size());
}

// Test enabling of simulcast with Plan B semantics.
// This test creating an answer.
TEST_F(PeerConnectionMediaTestPlanB, SimulcastAnswer) {
  auto caller = CreatePeerConnection();
  caller->AddVideoTrack("v0");
  auto offer = caller->CreateOffer();
  auto callee = CreatePeerConnection();
  auto callee_video_track = callee->AddVideoTrack("v1");
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  RTCOfferAnswerOptions options;
  options.num_simulcast_layers = 3;
  auto answer = callee->CreateAnswer(options);
  auto* description = cricket::GetFirstMediaContent(answer->description(),
                                                    cricket::MEDIA_TYPE_VIDEO)
                          ->media_description();
  ASSERT_EQ(1u, description->streams().size());
  ASSERT_TRUE(description->streams()[0].get_ssrc_group("SIM"));
  EXPECT_EQ(3u, description->streams()[0].get_ssrc_group("SIM")->ssrcs.size());

  // Check that it actually creates simulcast aswell.
  callee->SetLocalDescription(std::move(answer));
  auto senders = callee->pc()->GetSenders();
  ASSERT_EQ(1u, senders.size());
  EXPECT_EQ(cricket::MediaType::MEDIA_TYPE_VIDEO, senders[0]->media_type());
  EXPECT_EQ(3u, senders[0]->GetParameters().encodings.size());
}

// Test that stopping the callee transceivers causes the media channels to be
// destroyed on the callee after calling SetLocalDescription on the local
// answer.
// See next test for equivalent behavior with Plan B semantics.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       StoppedLocalTransceiversRemovesMediaChannels) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  // Stop both audio and video transceivers on the callee.
  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  transceivers[0]->StopInternal();
  transceivers[1]->StopInternal();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  EXPECT_TRUE(callee->pc()->GetTransceivers().empty());
}

// Test that removing streams from a subsequent answer causes the send streams
// on the callee to be removed when applied locally.
// See previous test for equivalent behavior with Unified Plan semantics.
TEST_F(PeerConnectionMediaTestPlanB, EmptyLocalAnswerRemovesSendStreams) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();
  auto callee_audio_track = callee->AddAudioTrack("a");
  auto callee_video_track = callee->AddVideoTrack("v");

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  // Remove both tracks from callee.
  callee->pc()->RemoveTrackOrError(callee_audio_track);
  callee->pc()->RemoveTrackOrError(callee_video_track);

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  EXPECT_TRUE(callee->pc()->GetSenders().empty());
  EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
}

// Test that a new stream in a subsequent offer causes a new receive stream to
// be created on the callee.
TEST_P(PeerConnectionMediaTest, NewStreamInRemoteOfferAddsRecvStreams) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  // Add second set of tracks to the caller.
  caller->AddAudioTrack("a2");
  caller->AddVideoTrack("v2");

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  if (IsUnifiedPlan()) {
    auto a1 = VoiceMediaReceiveChannel(callee->pc()->GetTransceivers()[0]);
    auto a2 = VoiceMediaReceiveChannel(callee->pc()->GetTransceivers()[2]);
    auto v1 = VideoMediaReceiveChannel(callee->pc()->GetTransceivers()[1]);
    auto v2 = VideoMediaReceiveChannel(callee->pc()->GetTransceivers()[3]);

    ASSERT_TRUE(a1);
    EXPECT_EQ(1u, a1->recv_streams().size());
    ASSERT_TRUE(a2);
    EXPECT_EQ(1u, a2->recv_streams().size());
    ASSERT_TRUE(v1);
    EXPECT_EQ(1u, v1->recv_streams().size());
    ASSERT_TRUE(v2);
    EXPECT_EQ(1u, v2->recv_streams().size());
  } else {
    EXPECT_EQ(4u, callee->pc()->GetReceivers().size());
  }
}

// Test that a new stream in a subsequent answer causes a new send stream to be
// created on the callee when added locally.
TEST_P(PeerConnectionMediaTest, NewStreamInLocalAnswerAddsSendStreams) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnectionWithAudioVideo();

  RTCOfferAnswerOptions offer_options;
  offer_options.offer_to_receive_audio =
      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
  offer_options.offer_to_receive_video =
      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
  RTCOfferAnswerOptions answer_options;

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get(), offer_options,
                                              answer_options));

  // Add second set of tracks to the callee.
  callee->AddAudioTrack("a2");
  callee->AddVideoTrack("v2");

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get(), offer_options,
                                              answer_options));

  if (IsUnifiedPlan()) {
    auto callee_voice =
        VoiceMediaSendChannel(callee->pc()->GetTransceivers()[0]);
    ASSERT_TRUE(callee_voice);
    auto callee_video =
        VideoMediaSendChannel(callee->pc()->GetTransceivers()[1]);
    ASSERT_TRUE(callee_video);

    EXPECT_EQ(1u, callee_voice->send_streams().size());
    EXPECT_EQ(1u, callee_video->send_streams().size());
  } else {
    EXPECT_EQ(4u, callee->pc()->GetSenders().size());
  }
}

// A PeerConnection with no local streams and no explicit answer constraints
// should not reject any offered media sections.
TEST_P(PeerConnectionMediaTest,
       CreateAnswerWithNoStreamsAndDefaultOptionsDoesNotReject) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  auto answer = callee->CreateAnswer();

  const auto* audio_content =
      cricket::GetFirstAudioContent(answer->description());
  ASSERT_TRUE(audio_content);
  EXPECT_FALSE(audio_content->rejected);

  const auto* video_content =
      cricket::GetFirstVideoContent(answer->description());
  ASSERT_TRUE(video_content);
  EXPECT_FALSE(video_content->rejected);
}

// Test that raw packetization is not set in the offer by default.
TEST_P(PeerConnectionMediaTest, RawPacketizationNotSetInOffer) {
  std::vector<cricket::Codec> fake_codecs;
  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
  fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111));
  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
  fake_codecs.push_back(
      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetVideoCodecs(fake_codecs);

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
  auto offer = caller->CreateOfferAndSetAsLocal();
  auto* offer_description =
      cricket::GetFirstVideoContentDescription(offer->description());
  for (const auto& codec : offer_description->codecs()) {
    EXPECT_EQ(codec.packetization, absl::nullopt);
  }
}

// Test that raw packetization is set in the offer and answer for all
// video payload when raw_packetization_for_video is true.
TEST_P(PeerConnectionMediaTest, RawPacketizationSetInOfferAndAnswer) {
  std::vector<cricket::Codec> fake_codecs;
  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
  fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111));
  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
  fake_codecs.push_back(
      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetVideoCodecs(fake_codecs);
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetVideoCodecs(fake_codecs);

  RTCOfferAnswerOptions options;
  options.raw_packetization_for_video = true;

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
  auto offer = caller->CreateOfferAndSetAsLocal(options);
  auto* offer_description =
      cricket::GetFirstVideoContentDescription(offer->description());
  for (const auto& codec : offer_description->codecs()) {
    if (codec.IsMediaCodec()) {
      EXPECT_EQ(codec.packetization, cricket::kPacketizationParamRaw);
    }
  }

  auto callee = CreatePeerConnectionWithVideo(std::move(callee_fake_engine));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  auto answer = callee->CreateAnswerAndSetAsLocal(options);
  auto* answer_description =
      cricket::GetFirstVideoContentDescription(answer->description());
  for (const auto& codec : answer_description->codecs()) {
    if (codec.IsMediaCodec()) {
      EXPECT_EQ(codec.packetization, cricket::kPacketizationParamRaw);
    }
  }

  ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
}

// Test that raw packetization is not set in the answer when
// raw_packetization_for_video is true if it was not set in the offer.
TEST_P(PeerConnectionMediaTest,
       RawPacketizationNotSetInAnswerWhenNotSetInOffer) {
  std::vector<cricket::Codec> fake_codecs;
  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
  fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111));
  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
  fake_codecs.push_back(
      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetVideoCodecs(fake_codecs);
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetVideoCodecs(fake_codecs);

  RTCOfferAnswerOptions caller_options;
  caller_options.raw_packetization_for_video = false;
  RTCOfferAnswerOptions callee_options;
  callee_options.raw_packetization_for_video = true;

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
  auto offer = caller->CreateOfferAndSetAsLocal(caller_options);

  auto callee = CreatePeerConnectionWithVideo(std::move(callee_fake_engine));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  auto answer = callee->CreateAnswerAndSetAsLocal(callee_options);

  auto* answer_description =
      cricket::GetFirstVideoContentDescription(answer->description());
  for (const auto& codec : answer_description->codecs()) {
    EXPECT_EQ(codec.packetization, absl::nullopt);
  }

  ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
}

class PeerConnectionMediaOfferDirectionTest
    : public PeerConnectionMediaBaseTest,
      public ::testing::WithParamInterface<
          std::tuple<SdpSemantics,
                     std::tuple<bool, int, RtpTransceiverDirection>>> {
 protected:
  PeerConnectionMediaOfferDirectionTest()
      : PeerConnectionMediaBaseTest(std::get<0>(GetParam())) {
    auto param = std::get<1>(GetParam());
    send_media_ = std::get<0>(param);
    offer_to_receive_ = std::get<1>(param);
    expected_direction_ = std::get<2>(param);
  }

  bool send_media_;
  int offer_to_receive_;
  RtpTransceiverDirection expected_direction_;
};

// Tests that the correct direction is set on the media description according
// to the presence of a local media track and the offer_to_receive setting.
TEST_P(PeerConnectionMediaOfferDirectionTest, VerifyDirection) {
  auto caller = CreatePeerConnection();
  if (send_media_) {
    caller->AddAudioTrack("a");
  }

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = offer_to_receive_;
  auto offer = caller->CreateOffer(options);

  auto* content = cricket::GetFirstMediaContent(offer->description(),
                                                cricket::MEDIA_TYPE_AUDIO);
  if (expected_direction_ == RtpTransceiverDirection::kInactive) {
    EXPECT_FALSE(content);
  } else {
    EXPECT_EQ(expected_direction_, content->media_description()->direction());
  }
}

// Note that in these tests, MD_INACTIVE indicates that no media section is
// included in the offer, not that the media direction is inactive.
INSTANTIATE_TEST_SUITE_P(
    PeerConnectionMediaTest,
    PeerConnectionMediaOfferDirectionTest,
    Combine(
        Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
        Values(std::make_tuple(false, -1, RtpTransceiverDirection::kInactive),
               std::make_tuple(false, 0, RtpTransceiverDirection::kInactive),
               std::make_tuple(false, 1, RtpTransceiverDirection::kRecvOnly),
               std::make_tuple(true, -1, RtpTransceiverDirection::kSendRecv),
               std::make_tuple(true, 0, RtpTransceiverDirection::kSendOnly),
               std::make_tuple(true, 1, RtpTransceiverDirection::kSendRecv))));

class PeerConnectionMediaAnswerDirectionTest
    : public PeerConnectionMediaBaseTest,
      public ::testing::WithParamInterface<
          std::tuple<SdpSemantics, RtpTransceiverDirection, bool, int>> {
 protected:
  PeerConnectionMediaAnswerDirectionTest()
      : PeerConnectionMediaBaseTest(std::get<0>(GetParam())) {
    offer_direction_ = std::get<1>(GetParam());
    send_media_ = std::get<2>(GetParam());
    offer_to_receive_ = std::get<3>(GetParam());
  }

  RtpTransceiverDirection offer_direction_;
  bool send_media_;
  int offer_to_receive_;
};

// Tests that the direction in an answer is correct according to direction sent
// in the offer, the presence of a local media track on the receive side and the
// offer_to_receive setting.
TEST_P(PeerConnectionMediaAnswerDirectionTest, VerifyDirection) {
  if (IsUnifiedPlan() &&
      offer_to_receive_ != RTCOfferAnswerOptions::kUndefined) {
    // offer_to_receive_ is not implemented when creating answers with Unified
    // Plan semantics specified.
    return;
  }

  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");

  // Create the offer with an audio section and set its direction.
  auto offer = caller->CreateOffer();
  cricket::GetFirstAudioContentDescription(offer->description())
      ->set_direction(offer_direction_);

  auto callee = CreatePeerConnection();
  if (send_media_) {
    callee->AddAudioTrack("a");
  }
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));

  // Create the answer according to the test parameters.
  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = offer_to_receive_;
  auto answer = callee->CreateAnswer(options);

  // The expected direction in the answer is the intersection of each side's
  // capability to send/recv media.
  // For the offerer, the direction is given in the offer (offer_direction_).
  // For the answerer, the direction has two components:
  // 1. Send if the answerer has a local track to send.
  // 2. Receive if the answerer has explicitly set the offer_to_receive to 1 or
  //    if it has been left as default.
  bool offer_send = RtpTransceiverDirectionHasSend(offer_direction_);
  bool offer_recv = RtpTransceiverDirectionHasRecv(offer_direction_);

  // The negotiated components determine the direction set in the answer.
  bool negotiate_send = (send_media_ && offer_recv);
  bool negotiate_recv = ((offer_to_receive_ != 0) && offer_send);

  auto expected_direction =
      RtpTransceiverDirectionFromSendRecv(negotiate_send, negotiate_recv);
  EXPECT_EQ(expected_direction,
            GetMediaContentDirection(answer.get(), cricket::MEDIA_TYPE_AUDIO));
}

// Tests that the media section is rejected if and only if the callee has no
// local media track and has set offer_to_receive to 0, no matter which
// direction the caller indicated in the offer.
TEST_P(PeerConnectionMediaAnswerDirectionTest, VerifyRejected) {
  if (IsUnifiedPlan() &&
      offer_to_receive_ != RTCOfferAnswerOptions::kUndefined) {
    // offer_to_receive_ is not implemented when creating answers with Unified
    // Plan semantics specified.
    return;
  }

  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");

  // Create the offer with an audio section and set its direction.
  auto offer = caller->CreateOffer();
  cricket::GetFirstAudioContentDescription(offer->description())
      ->set_direction(offer_direction_);

  auto callee = CreatePeerConnection();
  if (send_media_) {
    callee->AddAudioTrack("a");
  }
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));

  // Create the answer according to the test parameters.
  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = offer_to_receive_;
  auto answer = callee->CreateAnswer(options);

  // The media section is rejected if and only if offer_to_receive is explicitly
  // set to 0 and there is no media to send.
  auto* audio_content = cricket::GetFirstAudioContent(answer->description());
  ASSERT_TRUE(audio_content);
  EXPECT_EQ((offer_to_receive_ == 0 && !send_media_), audio_content->rejected);
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionMediaTest,
                         PeerConnectionMediaAnswerDirectionTest,
                         Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
                                        SdpSemantics::kUnifiedPlan),
                                 Values(RtpTransceiverDirection::kInactive,
                                        RtpTransceiverDirection::kSendOnly,
                                        RtpTransceiverDirection::kRecvOnly,
                                        RtpTransceiverDirection::kSendRecv),
                                 Bool(),
                                 Values(-1, 0, 1)));

TEST_P(PeerConnectionMediaTest, OfferHasDifferentDirectionForAudioVideo) {
  auto caller = CreatePeerConnection();
  caller->AddVideoTrack("v");

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 1;
  options.offer_to_receive_video = 0;
  auto offer = caller->CreateOffer(options);

  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly,
            GetMediaContentDirection(offer.get(), cricket::MEDIA_TYPE_AUDIO));
  EXPECT_EQ(RtpTransceiverDirection::kSendOnly,
            GetMediaContentDirection(offer.get(), cricket::MEDIA_TYPE_VIDEO));
}

TEST_P(PeerConnectionMediaTest, AnswerHasDifferentDirectionsForAudioVideo) {
  if (IsUnifiedPlan()) {
    // offer_to_receive_ is not implemented when creating answers with Unified
    // Plan semantics specified.
    return;
  }

  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();
  callee->AddVideoTrack("v");

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 1;
  options.offer_to_receive_video = 0;
  auto answer = callee->CreateAnswer(options);

  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly,
            GetMediaContentDirection(answer.get(), cricket::MEDIA_TYPE_AUDIO));
  EXPECT_EQ(RtpTransceiverDirection::kSendOnly,
            GetMediaContentDirection(answer.get(), cricket::MEDIA_TYPE_VIDEO));
}

void AddComfortNoiseCodecsToSend(cricket::FakeMediaEngine* media_engine) {
  const cricket::Codec kComfortNoiseCodec8k =
      cricket::CreateAudioCodec(102, cricket::kCnCodecName, 8000, 1);
  const cricket::Codec kComfortNoiseCodec16k =
      cricket::CreateAudioCodec(103, cricket::kCnCodecName, 16000, 1);

  auto codecs = media_engine->voice().send_codecs();
  codecs.push_back(kComfortNoiseCodec8k);
  codecs.push_back(kComfortNoiseCodec16k);
  media_engine->SetAudioCodecs(codecs);
}

bool HasAnyComfortNoiseCodecs(const cricket::SessionDescription* desc) {
  const auto* audio_desc = cricket::GetFirstAudioContentDescription(desc);
  for (const auto& codec : audio_desc->codecs()) {
    if (codec.name == cricket::kCnCodecName) {
      return true;
    }
  }
  return false;
}

bool HasPayloadTypeConflict(const cricket::SessionDescription* desc) {
  std::set<int> payload_types;
  const auto* audio_desc = cricket::GetFirstAudioContentDescription(desc);
  if (audio_desc) {
    for (const auto& codec : audio_desc->codecs()) {
      if (payload_types.count(codec.id) > 0) {
        return true;
      }
      payload_types.insert(codec.id);
    }
  }
  const auto* video_desc = cricket::GetFirstVideoContentDescription(desc);
  if (video_desc) {
    for (const auto& codec : video_desc->codecs()) {
      if (payload_types.count(codec.id) > 0) {
        return true;
      }
      payload_types.insert(codec.id);
    }
  }
  return false;
}

TEST_P(PeerConnectionMediaTest,
       CreateOfferWithNoVoiceActivityDetectionIncludesNoComfortNoiseCodecs) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(fake_engine.get());
  auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));

  RTCOfferAnswerOptions options;
  options.voice_activity_detection = false;
  auto offer = caller->CreateOffer(options);

  EXPECT_FALSE(HasAnyComfortNoiseCodecs(offer->description()));
}

TEST_P(PeerConnectionMediaTest,
       CreateOfferWithVoiceActivityDetectionIncludesComfortNoiseCodecs) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(fake_engine.get());
  auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));

  RTCOfferAnswerOptions options;
  options.voice_activity_detection = true;
  auto offer = caller->CreateOffer(options);

  EXPECT_TRUE(HasAnyComfortNoiseCodecs(offer->description()));
}

TEST_P(PeerConnectionMediaTest,
       CreateAnswerWithVoiceActivityDetectionIncludesNoComfortNoiseCodecs) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(callee_fake_engine.get());
  auto callee =
      CreatePeerConnectionWithAudioVideo(std::move(callee_fake_engine));

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  RTCOfferAnswerOptions options;
  options.voice_activity_detection = true;
  auto answer = callee->CreateAnswer(options);

  EXPECT_FALSE(HasAnyComfortNoiseCodecs(answer->description()));
}

TEST_P(PeerConnectionMediaTest,
       CreateAnswerWithNoVoiceActivityDetectionIncludesNoComfortNoiseCodecs) {
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(caller_fake_engine.get());
  auto caller =
      CreatePeerConnectionWithAudioVideo(std::move(caller_fake_engine));

  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(callee_fake_engine.get());
  auto callee =
      CreatePeerConnectionWithAudioVideo(std::move(callee_fake_engine));

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  RTCOfferAnswerOptions options;
  options.voice_activity_detection = false;
  auto answer = callee->CreateAnswer(options);

  EXPECT_FALSE(HasAnyComfortNoiseCodecs(answer->description()));
}

// The following test group verifies that we reject answers with invalid media
// sections as per RFC 3264.

class PeerConnectionMediaInvalidMediaTest
    : public PeerConnectionMediaBaseTest,
      public ::testing::WithParamInterface<std::tuple<
          SdpSemantics,
          std::tuple<std::string,
                     std::function<void(cricket::SessionDescription*)>,
                     std::string>>> {
 protected:
  PeerConnectionMediaInvalidMediaTest()
      : PeerConnectionMediaBaseTest(std::get<0>(GetParam())) {
    auto param = std::get<1>(GetParam());
    mutator_ = std::get<1>(param);
    expected_error_ = std::get<2>(param);
  }

  std::function<void(cricket::SessionDescription*)> mutator_;
  std::string expected_error_;
};

TEST_P(PeerConnectionMediaInvalidMediaTest, FailToSetRemoteAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto answer = callee->CreateAnswer();
  mutator_(answer->description());

  std::string error;
  ASSERT_FALSE(caller->SetRemoteDescription(std::move(answer), &error));
  EXPECT_EQ("Failed to set remote answer sdp: " + expected_error_, error);
}

TEST_P(PeerConnectionMediaInvalidMediaTest, FailToSetLocalAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto answer = callee->CreateAnswer();
  mutator_(answer->description());

  std::string error;
  ASSERT_FALSE(callee->SetLocalDescription(std::move(answer), &error));
  EXPECT_EQ("Failed to set local answer sdp: " + expected_error_, error);
}

void RemoveVideoContentAndUnbundle(cricket::SessionDescription* desc) {
  // Removing BUNDLE is easier than removing the content in there.
  desc->RemoveGroupByName("BUNDLE");
  auto content_name = cricket::GetFirstVideoContent(desc)->name;
  desc->RemoveContentByName(content_name);
  desc->RemoveTransportInfoByName(content_name);
}

void RenameVideoContentAndUnbundle(cricket::SessionDescription* desc) {
  // Removing BUNDLE is easier than renaming the content in there.
  desc->RemoveGroupByName("BUNDLE");
  auto* video_content = cricket::GetFirstVideoContent(desc);
  auto* transport_info = desc->GetTransportInfoByName(video_content->name);
  video_content->name = "video_renamed";
  transport_info->content_name = video_content->name;
}

void ReverseMediaContent(cricket::SessionDescription* desc) {
  absl::c_reverse(desc->contents());
  absl::c_reverse(desc->transport_infos());
}

void ChangeMediaTypeAudioToVideo(cricket::SessionDescription* desc) {
  std::string audio_mid = cricket::GetFirstAudioContent(desc)->name;
  desc->RemoveContentByName(audio_mid);
  auto* video_content = cricket::GetFirstVideoContent(desc);
  desc->AddContent(audio_mid, video_content->type,
                   video_content->media_description()->Clone());
}

constexpr char kMLinesOutOfOrder[] =
    "The order of m-lines in answer doesn't match order in offer. Rejecting "
    "answer.";

INSTANTIATE_TEST_SUITE_P(
    PeerConnectionMediaTest,
    PeerConnectionMediaInvalidMediaTest,
    Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
            Values(std::make_tuple("remove video",
                                   RemoveVideoContentAndUnbundle,
                                   kMLinesOutOfOrder),
                   std::make_tuple("rename video",
                                   RenameVideoContentAndUnbundle,
                                   kMLinesOutOfOrder),
                   std::make_tuple("reverse media sections",
                                   ReverseMediaContent,
                                   kMLinesOutOfOrder),
                   std::make_tuple("change audio type to video type",
                                   ChangeMediaTypeAudioToVideo,
                                   kMLinesOutOfOrder))));

// Tests that if the underlying video encoder fails to be initialized (signaled
// by failing to set send codecs), the PeerConnection signals the error to the
// client.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       MediaEngineErrorPropagatedToClients) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto video_channel =
      VideoMediaSendChannel(caller->pc()->GetTransceivers()[1]);
  video_channel->set_fail_set_send_codecs(true);

  std::string error;
  ASSERT_FALSE(caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal(),
                                            &error));
  EXPECT_EQ(std::string("Failed to set remote answer sdp: Failed to set remote "
                        "video description "
                        "send parameters for m-section with mid='") +
                (IsUnifiedPlan() ? "1" : "video") + "'.",
            error);
}

// Tests that if the underlying video encoder fails once then subsequent
// attempts at setting the local/remote description will also fail, even if
// SetSendCodecs no longer fails.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       FailToApplyDescriptionIfVideoEncoderHasEverFailed) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto video_channel =
      VideoMediaSendChannel(caller->pc()->GetTransceivers()[1]);
  video_channel->set_fail_set_send_codecs(true);

  EXPECT_FALSE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  video_channel->set_fail_set_send_codecs(false);

  EXPECT_FALSE(caller->SetRemoteDescription(callee->CreateAnswer()));
  EXPECT_FALSE(caller->SetLocalDescription(caller->CreateOffer()));
}

void RenameContent(cricket::SessionDescription* desc,
                   cricket::MediaType media_type,
                   const std::string& new_name) {
  auto* content = cricket::GetFirstMediaContent(desc, media_type);
  RTC_DCHECK(content);
  std::string old_name = content->name;
  content->name = new_name;
  auto* transport = desc->GetTransportInfoByName(old_name);
  RTC_DCHECK(transport);
  transport->content_name = new_name;

  // Rename the content name in the BUNDLE group.
  cricket::ContentGroup new_bundle_group =
      *desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
  new_bundle_group.RemoveContentName(old_name);
  new_bundle_group.AddContentName(new_name);
  desc->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
  desc->AddGroup(new_bundle_group);
}

// Tests that an answer responds with the same MIDs as the offer.
TEST_P(PeerConnectionMediaTest, AnswerHasSameMidsAsOffer) {
  const std::string kAudioMid = "notdefault1";
  const std::string kVideoMid = "notdefault2";

  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  auto offer = caller->CreateOffer();
  RenameContent(offer->description(), cricket::MEDIA_TYPE_AUDIO, kAudioMid);
  RenameContent(offer->description(), cricket::MEDIA_TYPE_VIDEO, kVideoMid);
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));

  auto answer = callee->CreateAnswer();
  EXPECT_EQ(kAudioMid,
            cricket::GetFirstAudioContent(answer->description())->name);
  EXPECT_EQ(kVideoMid,
            cricket::GetFirstVideoContent(answer->description())->name);
}

// Test that if the callee creates a re-offer, the MIDs are the same as the
// original offer.
TEST_P(PeerConnectionMediaTest, ReOfferHasSameMidsAsFirstOffer) {
  const std::string kAudioMid = "notdefault1";
  const std::string kVideoMid = "notdefault2";

  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  auto offer = caller->CreateOffer();
  RenameContent(offer->description(), cricket::MEDIA_TYPE_AUDIO, kAudioMid);
  RenameContent(offer->description(), cricket::MEDIA_TYPE_VIDEO, kVideoMid);
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));

  auto reoffer = callee->CreateOffer();
  EXPECT_EQ(kAudioMid,
            cricket::GetFirstAudioContent(reoffer->description())->name);
  EXPECT_EQ(kVideoMid,
            cricket::GetFirstVideoContent(reoffer->description())->name);
}

// Test that SetRemoteDescription returns an error if there are two m= sections
// with the same MID value.
TEST_P(PeerConnectionMediaTest, SetRemoteDescriptionFailsWithDuplicateMids) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  auto offer = caller->CreateOffer();
  RenameContent(offer->description(), cricket::MEDIA_TYPE_AUDIO, "same");
  RenameContent(offer->description(), cricket::MEDIA_TYPE_VIDEO, "same");

  std::string error;
  EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer), &error));
  EXPECT_EQ(error,
            "Failed to set remote offer sdp: Duplicate a=mid value 'same'.");
}

// Test that if a RED codec refers to another codec in its fmtp line, but that
// codec's payload type was reassigned for some reason (either the remote
// endpoint selected a different payload type or there was a conflict), the RED
// fmtp line is modified to refer to the correct payload type.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeReassigned) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "120/120");
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  ASSERT_EQ(1u, answer_description->codecs().size());

  // Offer from the callee should respect the established payload type, and
  // attempt to add RED, which should refer to the correct payload type.
  offer = callee->CreateOfferAndSetAsLocal();
  auto* offer_description =
      cricket::GetFirstAudioContentDescription(offer->description());
  ASSERT_EQ(2u, offer_description->codecs().size());
  for (const auto& codec : offer_description->codecs()) {
    if (codec.name == "foo") {
      ASSERT_EQ(100, codec.id);
    } else if (codec.name == cricket::kRedCodecName) {
      std::string fmtp;
      ASSERT_TRUE(codec.GetParam("", &fmtp));
      EXPECT_EQ("100/100", fmtp);
    }
  }
}

// Test that RED without fmtp does match RED without fmtp.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeNoFmtpMatchNoFmtp) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  caller_fake_codecs.push_back(
      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  // Red (without fmtp) is negotiated.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  ASSERT_EQ(2u, answer_description->codecs().size());

  // Offer from the callee should respect the established payload type, and
  // attempt to add RED.
  offer = callee->CreateOfferAndSetAsLocal();
  auto* offer_description =
      cricket::GetFirstAudioContentDescription(offer->description());
  ASSERT_EQ(2u, offer_description->codecs().size());
  for (const auto& codec : offer_description->codecs()) {
    if (codec.name == "foo") {
      ASSERT_EQ(100, codec.id);
    } else if (codec.name == cricket::kRedCodecName) {
      ASSERT_EQ(101, codec.id);
    }
  }
}

// Test that RED without fmtp does not match RED with fmtp.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeNoFmtpNoMatchFmtp) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  caller_fake_codecs.push_back(
      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "120/120");
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  // It should not negotiate RED.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  ASSERT_EQ(1u, answer_description->codecs().size());

  // Offer from the callee should respect the established payload type, and
  // attempt to add RED, which should refer to the correct payload type.
  offer = callee->CreateOfferAndSetAsLocal();
  auto* offer_description =
      cricket::GetFirstAudioContentDescription(offer->description());
  ASSERT_EQ(2u, offer_description->codecs().size());
  for (const auto& codec : offer_description->codecs()) {
    if (codec.name == "foo") {
      ASSERT_EQ(100, codec.id);
    } else if (codec.name == cricket::kRedCodecName) {
      std::string fmtp;
      ASSERT_TRUE(
          codec.GetParam(cricket::kCodecParamNotInNameValueFormat, &fmtp));
      EXPECT_EQ("100/100", fmtp);
    }
  }
}

// Test that RED with fmtp must match base codecs.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeMustMatchBaseCodecs) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  caller_fake_codecs.push_back(
      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
  caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "100/100");
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(122, "bar", 0, 1));
  callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "122/122");
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  // It should not negotiate RED since RED is associated with foo, not bar.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  ASSERT_EQ(1u, answer_description->codecs().size());
}

// Test behaviour when the RED fmtp attempts to specify different codecs
// which is not supported.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadMixed) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(102, "bar", 0, 1));
  caller_fake_codecs.push_back(
      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
  caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "100/102");
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "120/120");
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  // RED is not negotiated.
  ASSERT_EQ(1u, answer_description->codecs().size());
}

// Test behaviour when the RED fmtp attempts to negotiate different levels of
// redundancy.
TEST_P(PeerConnectionMediaTest, RedFmtpPayloadDifferentRedundancy) {
  std::vector<cricket::Codec> caller_fake_codecs;
  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  caller_fake_codecs.push_back(
      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
  caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "100/100");
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
  auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));

  std::vector<cricket::Codec> callee_fake_codecs;
  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
  callee_fake_codecs.push_back(
      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
  callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                     "120/120/120");
  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
  auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));

  // Offer from the caller establishes 100 as the "foo" payload type.
  auto offer = caller->CreateOfferAndSetAsLocal();
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswerAndSetAsLocal();
  auto answer_description =
      cricket::GetFirstAudioContentDescription(answer->description());
  // RED is negotiated.
  ASSERT_EQ(2u, answer_description->codecs().size());

  // Offer from the callee should respect the established payload type, and
  // attempt to add RED, which should refer to the correct payload type.
  offer = callee->CreateOfferAndSetAsLocal();
  auto* offer_description =
      cricket::GetFirstAudioContentDescription(offer->description());
  ASSERT_EQ(2u, offer_description->codecs().size());
  for (const auto& codec : offer_description->codecs()) {
    if (codec.name == "foo") {
      ASSERT_EQ(100, codec.id);
    } else if (codec.name == cricket::kRedCodecName) {
      std::string fmtp;
      ASSERT_TRUE(
          codec.GetParam(cricket::kCodecParamNotInNameValueFormat, &fmtp));
      EXPECT_EQ("100/100", fmtp);
    }
  }
}

template <typename C>
bool CompareCodecs(const std::vector<RtpCodecCapability>& capabilities,
                   const std::vector<C>& codecs) {
  bool capability_has_rtx =
      absl::c_any_of(capabilities, [](const RtpCodecCapability& codec) {
        return codec.name == cricket::kRtxCodecName;
      });
  bool codecs_has_rtx = absl::c_any_of(codecs, [](const C& codec) {
    return codec.name == cricket::kRtxCodecName;
  });

  std::vector<C> codecs_no_rtx;
  absl::c_copy_if(
      codecs, std::back_inserter(codecs_no_rtx),
      [](const C& codec) { return codec.name != cricket::kRtxCodecName; });

  std::vector<RtpCodecCapability> capabilities_no_rtx;
  absl::c_copy_if(capabilities, std::back_inserter(capabilities_no_rtx),
                  [](const RtpCodecCapability& codec) {
                    return codec.name != cricket::kRtxCodecName;
                  });

  return capability_has_rtx == codecs_has_rtx &&
         absl::c_equal(
             capabilities_no_rtx, codecs_no_rtx,
             [](const RtpCodecCapability& capability, const C& codec) {
               return codec.MatchesRtpCodec(capability);
             });
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAudioMissingRecvCodec) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  auto send_codecs = fake_engine->voice().send_codecs();
  send_codecs.push_back(cricket::CreateAudioCodec(send_codecs.back().id + 1,
                                                  "send_only_codec", 0, 1));
  fake_engine->SetAudioSendCodecs(send_codecs);

  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);

  std::vector<RtpCodecCapability> codecs;
  absl::c_copy_if(capabilities.codecs, std::back_inserter(codecs),
                  [](const RtpCodecCapability& codec) {
                    return codec.name.find("_only_") != std::string::npos;
                  });

  auto result = transceiver->SetCodecPreferences(codecs);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAudioRejectsVideoCodec) {
  auto caller = CreatePeerConnectionWithAudio();

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto video_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_VIDEO)
          .codecs;
  auto codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_AUDIO)
          .codecs;
  codecs.insert(codecs.end(), video_codecs.begin(), video_codecs.end());
  auto result = transceiver->SetCodecPreferences(codecs);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAudioRejectsOnlyRtxRedFec) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  auto audio_codecs = fake_engine->voice().send_codecs();
  audio_codecs.push_back(cricket::CreateAudioRtxCodec(
      audio_codecs.back().id + 1, audio_codecs.back().id));
  audio_codecs.push_back(cricket::CreateAudioCodec(
      audio_codecs.back().id + 1, cricket::kRedCodecName, 0, 1));
  audio_codecs.push_back(cricket::CreateAudioCodec(
      audio_codecs.back().id + 1, cricket::kUlpfecCodecName, 0, 1));
  fake_engine->SetAudioCodecs(audio_codecs);

  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_AUDIO)
          .codecs;
  auto codecs_only_rtx_red_fec = codecs;
  auto it = std::remove_if(codecs_only_rtx_red_fec.begin(),
                           codecs_only_rtx_red_fec.end(),
                           [](const RtpCodecCapability& codec) {
                             return !(codec.name == cricket::kRtxCodecName ||
                                      codec.name == cricket::kRedCodecName ||
                                      codec.name == cricket::kUlpfecCodecName);
                           });
  codecs_only_rtx_red_fec.erase(it, codecs_only_rtx_red_fec.end());

  auto result = transceiver->SetCodecPreferences(codecs_only_rtx_red_fec);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesAllAudioCodecs) {
  auto caller = CreatePeerConnectionWithAudio();

  auto sender_audio_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO)
          .codecs;

  auto audio_transceiver = caller->pc()->GetTransceivers().front();

  // Normal case, set all capabilities as preferences
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(sender_audio_codecs).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_TRUE(CompareCodecs(sender_audio_codecs, codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesResetAudioCodecs) {
  auto caller = CreatePeerConnectionWithAudio();

  auto sender_audio_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO)
          .codecs;
  std::vector<RtpCodecCapability> empty_codecs = {};

  auto audio_transceiver = caller->pc()->GetTransceivers().front();

  // Normal case, reset codec preferences
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(empty_codecs).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_TRUE(CompareCodecs(sender_audio_codecs, codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAudioSendOnlyKillswitch) {
  field_trials_ = std::make_unique<test::ScopedKeyValueConfig>(
      "WebRTC-SetCodecPreferences-ReceiveOnlyFilterInsteadOfThrow/Disabled/");
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  auto send_codecs = fake_engine->voice().send_codecs();
  send_codecs.push_back(cricket::CreateAudioCodec(send_codecs.back().id + 1,
                                                  "send_only_codec", 0, 1));
  fake_engine->SetAudioSendCodecs(send_codecs);

  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto send_capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);

  EXPECT_TRUE(transceiver->SetCodecPreferences(send_capabilities.codecs).ok());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoRejectsAudioCodec) {
  auto caller = CreatePeerConnectionWithVideo();

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto audio_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_AUDIO)
          .codecs;
  auto codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_VIDEO)
          .codecs;
  codecs.insert(codecs.end(), audio_codecs.begin(), audio_codecs.end());
  auto result = transceiver->SetCodecPreferences(codecs);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoRejectsOnlyRtxRedFec) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  auto video_codecs = fake_engine->video().send_codecs();
  video_codecs.push_back(cricket::CreateVideoRtxCodec(
      video_codecs.back().id + 1, video_codecs.back().id));
  video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
                                                   cricket::kRedCodecName));
  video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
                                                   cricket::kUlpfecCodecName));
  fake_engine->SetVideoCodecs(video_codecs);

  auto caller = CreatePeerConnectionWithVideo(std::move(fake_engine));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MediaType::MEDIA_TYPE_VIDEO)
          .codecs;
  auto codecs_only_rtx_red_fec = codecs;
  auto it = std::remove_if(codecs_only_rtx_red_fec.begin(),
                           codecs_only_rtx_red_fec.end(),
                           [](const RtpCodecCapability& codec) {
                             return !(codec.name == cricket::kRtxCodecName ||
                                      codec.name == cricket::kRedCodecName ||
                                      codec.name == cricket::kUlpfecCodecName);
                           });
  codecs_only_rtx_red_fec.erase(it, codecs_only_rtx_red_fec.end());

  auto result = transceiver->SetCodecPreferences(codecs_only_rtx_red_fec);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesAllVideoCodecs) {
  auto caller = CreatePeerConnectionWithVideo();

  auto sender_video_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
          .codecs;

  auto video_transceiver = caller->pc()->GetTransceivers().front();

  // Normal case, setting preferences to normal capabilities
  EXPECT_TRUE(video_transceiver->SetCodecPreferences(sender_video_codecs).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_TRUE(CompareCodecs(sender_video_codecs, codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesResetVideoCodecs) {
  auto caller = CreatePeerConnectionWithVideo();

  auto sender_video_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
          .codecs;

  std::vector<RtpCodecCapability> empty_codecs = {};

  auto video_transceiver = caller->pc()->GetTransceivers().front();

  // Normal case, resetting preferences with empty list of codecs
  EXPECT_TRUE(video_transceiver->SetCodecPreferences(empty_codecs).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_TRUE(CompareCodecs(sender_video_codecs, codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoSendOnlyKillswitch) {
  field_trials_ = std::make_unique<test::ScopedKeyValueConfig>(
      "WebRTC-SetCodecPreferences-ReceiveOnlyFilterInsteadOfThrow/Disabled/");
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  auto send_codecs = fake_engine->voice().send_codecs();
  send_codecs.push_back(
      cricket::CreateVideoCodec(send_codecs.back().id + 1, "send_only_codec"));
  fake_engine->SetAudioSendCodecs(send_codecs);

  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto send_capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);

  EXPECT_TRUE(transceiver->SetCodecPreferences(send_capabilities.codecs).ok());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoCodecDuplicatesRemoved) {
  auto caller = CreatePeerConnectionWithVideo();

  auto sender_video_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
          .codecs;

  auto video_transceiver = caller->pc()->GetTransceivers().front();

  // Check duplicates are removed
  auto single_codec = sender_video_codecs;
  single_codec.resize(1);
  auto duplicate_codec = single_codec;
  duplicate_codec.push_back(duplicate_codec.front());
  duplicate_codec.push_back(duplicate_codec.front());
  duplicate_codec.push_back(duplicate_codec.front());

  EXPECT_TRUE(video_transceiver->SetCodecPreferences(duplicate_codec).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_TRUE(CompareCodecs(single_codec, codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoWithRtx) {
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  auto caller_video_codecs = caller_fake_engine->video().send_codecs();
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_fake_engine->SetVideoCodecs(caller_video_codecs);

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));

  auto sender_video_codecs =
      caller->pc_factory()
          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
          .codecs;

  auto video_transceiver = caller->pc()->GetTransceivers().front();

  // Check that RTX codec is properly added
  auto video_codecs_vpx_rtx = sender_video_codecs;
  auto it =
      std::remove_if(video_codecs_vpx_rtx.begin(), video_codecs_vpx_rtx.end(),
                     [](const RtpCodecCapability& codec) {
                       return codec.name != cricket::kRtxCodecName &&
                              codec.name != cricket::kVp8CodecName &&
                              codec.name != cricket::kVp9CodecName;
                     });
  video_codecs_vpx_rtx.erase(it, video_codecs_vpx_rtx.end());
  absl::c_reverse(video_codecs_vpx_rtx);
  EXPECT_EQ(video_codecs_vpx_rtx.size(), 3u);  // VP8, VP9, RTX
  EXPECT_TRUE(
      video_transceiver->SetCodecPreferences(video_codecs_vpx_rtx).ok());
  auto offer = caller->CreateOffer();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();

  EXPECT_TRUE(CompareCodecs(video_codecs_vpx_rtx, codecs));
  EXPECT_EQ(codecs.size(), 4u);
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoCodecsNegotiation) {
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  auto caller_video_codecs = caller_fake_engine->video().send_codecs();
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_fake_engine->SetVideoCodecs(caller_video_codecs);

  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetVideoCodecs(caller_video_codecs);

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
  auto callee = CreatePeerConnection(std::move(callee_fake_engine));

  auto video_codecs = caller->pc_factory()
                          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
                          .codecs;

  auto send_transceiver = caller->pc()->GetTransceivers().front();

  auto video_codecs_vpx = video_codecs;
  auto it = std::remove_if(video_codecs_vpx.begin(), video_codecs_vpx.end(),
                           [](const RtpCodecCapability& codec) {
                             return codec.name != cricket::kVp8CodecName &&
                                    codec.name != cricket::kVp9CodecName;
                           });
  video_codecs_vpx.erase(it, video_codecs_vpx.end());
  EXPECT_EQ(video_codecs_vpx.size(), 2u);  // VP8, VP9
  EXPECT_TRUE(send_transceiver->SetCodecPreferences(video_codecs_vpx).ok());

  auto offer = caller->CreateOfferAndSetAsLocal();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();

  EXPECT_EQ(codecs.size(), 2u);  // VP8, VP9
  EXPECT_TRUE(CompareCodecs(video_codecs_vpx, codecs));

  callee->SetRemoteDescription(std::move(offer));

  auto recv_transceiver = callee->pc()->GetTransceivers().front();
  auto video_codecs_vp8_rtx = video_codecs;
  it = std::remove_if(video_codecs_vp8_rtx.begin(), video_codecs_vp8_rtx.end(),
                      [](const RtpCodecCapability& codec) {
                        bool r = codec.name != cricket::kVp8CodecName &&
                                 codec.name != cricket::kRtxCodecName;
                        return r;
                      });
  video_codecs_vp8_rtx.erase(it, video_codecs_vp8_rtx.end());
  EXPECT_EQ(video_codecs_vp8_rtx.size(), 2u);  // VP8, RTX
  recv_transceiver->SetCodecPreferences(video_codecs_vp8_rtx);

  auto answer = callee->CreateAnswerAndSetAsLocal();

  auto recv_codecs = answer->description()
                         ->contents()[0]
                         .media_description()
                         ->codecs();
  EXPECT_EQ(recv_codecs.size(), 1u);  // VP8
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVideoCodecsNegotiationReverseOrder) {
  auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
  auto caller_video_codecs = caller_fake_engine->video().send_codecs();
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_video_codecs.push_back(cricket::CreateVideoCodec(
      caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
  caller_video_codecs.push_back(cricket::CreateVideoRtxCodec(
      caller_video_codecs.back().id + 1, caller_video_codecs.back().id));
  caller_fake_engine->SetVideoCodecs(caller_video_codecs);

  auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
  callee_fake_engine->SetVideoCodecs(caller_video_codecs);

  auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
  auto callee = CreatePeerConnection(std::move(callee_fake_engine));

  auto video_codecs = caller->pc_factory()
                          ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
                          .codecs;

  auto send_transceiver = caller->pc()->GetTransceivers().front();

  auto video_codecs_vpx = video_codecs;
  auto it = std::remove_if(video_codecs_vpx.begin(), video_codecs_vpx.end(),
                           [](const RtpCodecCapability& codec) {
                             return codec.name != cricket::kVp8CodecName &&
                                    codec.name != cricket::kVp9CodecName;
                           });
  video_codecs_vpx.erase(it, video_codecs_vpx.end());
  EXPECT_EQ(video_codecs_vpx.size(), 2u);  // VP8, VP9
  EXPECT_TRUE(send_transceiver->SetCodecPreferences(video_codecs_vpx).ok());

  auto video_codecs_vpx_reverse = video_codecs_vpx;
  absl::c_reverse(video_codecs_vpx_reverse);

  auto offer = caller->CreateOfferAndSetAsLocal();
  auto codecs = offer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  EXPECT_EQ(codecs.size(), 2u);  // VP9, VP8
  EXPECT_TRUE(CompareCodecs(video_codecs_vpx, codecs));

  callee->SetRemoteDescription(std::move(offer));

  auto recv_transceiver = callee->pc()->GetTransceivers().front();
  recv_transceiver->SetCodecPreferences(video_codecs_vpx_reverse);

  auto answer = callee->CreateAnswerAndSetAsLocal();

  auto recv_codecs = answer->description()
                         ->contents()[0]
                         .media_description()
                         ->codecs();

  EXPECT_TRUE(CompareCodecs(video_codecs_vpx_reverse, recv_codecs));
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesVoiceActivityDetection) {
  auto fake_engine = std::make_unique<FakeMediaEngine>();
  AddComfortNoiseCodecsToSend(fake_engine.get());
  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  RTCOfferAnswerOptions options;
  auto offer = caller->CreateOffer(options);
  EXPECT_TRUE(HasAnyComfortNoiseCodecs(offer->description()));

  auto transceiver = caller->pc()->GetTransceivers().front();
  auto capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);
  EXPECT_TRUE(transceiver->SetCodecPreferences(capabilities.codecs).ok());

  options.voice_activity_detection = false;
  offer = caller->CreateOffer(options);
  EXPECT_FALSE(HasAnyComfortNoiseCodecs(offer->description()));
}

// If the "default" payload types of audio/video codecs are the same, and
// audio/video are bundled (as is the default), payload types should be
// remapped to avoid conflict, as normally happens without using
// SetCodecPreferences.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAvoidsPayloadTypeConflictInOffer) {
  auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();

  std::vector<cricket::Codec> audio_codecs;
  audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100));
  fake_engine->SetAudioCodecs(audio_codecs);

  std::vector<cricket::Codec> video_codecs;
  video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar"));
  video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100));
  fake_engine->SetVideoCodecs(video_codecs);

  auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));
  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());

  auto audio_transceiver = caller->pc()->GetTransceivers()[0];
  auto capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  auto video_transceiver = caller->pc()->GetTransceivers()[1];
  capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_VIDEO);
  EXPECT_TRUE(video_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  RTCOfferAnswerOptions options;
  auto offer = caller->CreateOffer(options);
  EXPECT_FALSE(HasPayloadTypeConflict(offer->description()));
  // Sanity check that we got the primary codec and RTX.
  EXPECT_EQ(2u, cricket::GetFirstAudioContentDescription(offer->description())
                    ->codecs()
                    .size());
  EXPECT_EQ(2u, cricket::GetFirstVideoContentDescription(offer->description())
                    ->codecs()
                    .size());
}

// Same as above, but preferences set for the answer.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAvoidsPayloadTypeConflictInAnswer) {
  auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();

  std::vector<cricket::Codec> audio_codecs;
  audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100));
  fake_engine->SetAudioCodecs(audio_codecs);

  std::vector<cricket::Codec> video_codecs;
  video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar"));
  video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100));
  fake_engine->SetVideoCodecs(video_codecs);

  auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));

  RTCOfferAnswerOptions options;
  caller->SetRemoteDescription(caller->CreateOffer(options));

  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());

  auto audio_transceiver = caller->pc()->GetTransceivers()[0];
  auto capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  auto video_transceiver = caller->pc()->GetTransceivers()[1];
  capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_VIDEO);
  EXPECT_TRUE(video_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  auto answer = caller->CreateAnswer(options);

  EXPECT_FALSE(HasPayloadTypeConflict(answer->description()));
  // Sanity check that we got the primary codec and RTX.
  EXPECT_EQ(2u, cricket::GetFirstAudioContentDescription(answer->description())
                    ->codecs()
                    .size());
  EXPECT_EQ(2u, cricket::GetFirstVideoContentDescription(answer->description())
                    ->codecs()
                    .size());
}

// Same as above, but preferences set for a subsequent offer.
TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesAvoidsPayloadTypeConflictInSubsequentOffer) {
  auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();

  std::vector<cricket::Codec> audio_codecs;
  audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100));
  fake_engine->SetAudioCodecs(audio_codecs);

  std::vector<cricket::Codec> video_codecs;
  video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar"));
  video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100));
  fake_engine->SetVideoCodecs(video_codecs);

  auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));

  RTCOfferAnswerOptions options;
  caller->SetRemoteDescription(caller->CreateOffer(options));
  caller->SetLocalDescription(caller->CreateAnswer(options));

  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());

  auto audio_transceiver = caller->pc()->GetTransceivers()[0];
  auto capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  auto video_transceiver = caller->pc()->GetTransceivers()[1];
  capabilities = caller->pc_factory()->GetRtpSenderCapabilities(
      cricket::MediaType::MEDIA_TYPE_VIDEO);
  EXPECT_TRUE(video_transceiver->SetCodecPreferences(capabilities.codecs).ok());

  auto reoffer = caller->CreateOffer(options);
  ASSERT_THAT(reoffer, NotNull());

  EXPECT_FALSE(HasPayloadTypeConflict(reoffer->description()));
  // Sanity check that we got the primary codec and RTX.
  EXPECT_EQ(2u, cricket::GetFirstAudioContentDescription(reoffer->description())
                    ->codecs()
                    .size());
  EXPECT_EQ(2u, cricket::GetFirstVideoContentDescription(reoffer->description())
                    ->codecs()
                    .size());
}

TEST_F(PeerConnectionMediaTestUnifiedPlan,
       SetCodecPreferencesReceiveOnlyWithSendOnlyTransceiverStops) {
  auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();

  std::vector<cricket::Codec> audio_codecs;
  audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
  fake_engine->SetAudioRecvCodecs(audio_codecs);

  auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));

  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(1u, transceivers.size());

  auto audio_transceiver = caller->pc()->GetTransceivers()[0];
  auto error = audio_transceiver->SetDirectionWithError(
      RtpTransceiverDirection::kSendOnly);
  ASSERT_TRUE(error.ok());
  auto capabilities = caller->pc_factory()->GetRtpReceiverCapabilities(
      cricket::MediaType::MEDIA_TYPE_AUDIO);
  EXPECT_TRUE(audio_transceiver->SetCodecPreferences(capabilities.codecs).ok());
  RTCOfferAnswerOptions options;
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer(options)));
  EXPECT_EQ(audio_transceiver->direction(), RtpTransceiverDirection::kStopped);
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionMediaTest,
                         PeerConnectionMediaTest,
                         Values(SdpSemantics::kPlanB_DEPRECATED,
                                SdpSemantics::kUnifiedPlan));

}  // namespace webrtc
