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

#include <cstddef>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/create_modular_peer_connection_factory.h"
#include "api/enable_media_with_defaults.h"
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_receiver_interface.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/stats/rtcstats_objects.h"
#include "api/test/rtc_error_matchers.h"
#include "media/base/stream_params.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/transport_info.h"
#include "pc/media_session.h"
#include "pc/peer_connection.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/session_description.h"
#include "pc/test/fake_audio_capture_module.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/thread.h"
#include "test/create_test_environment.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/pc/sctp/fake_sctp_transport.h"
#include "test/run_loop.h"

#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif

// This file contains tests that ensure the PeerConnection's implementation of
// CreateOffer/CreateAnswer/SetLocalDescription/SetRemoteDescription conform
// to the JavaScript Session Establishment Protocol (JSEP).
// For now these semantics are only available when configuring the
// PeerConnection with Unified Plan, but eventually that will be the default.

namespace webrtc {

using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using ::testing::Combine;
using ::testing::ElementsAre;
using ::testing::NotNull;
using ::testing::SizeIs;
using ::testing::UnorderedElementsAre;
using ::testing::Values;

class PeerConnectionJsepTest : public ::testing::Test {
 protected:
  typedef std::unique_ptr<PeerConnectionWrapper> WrapperPtr;

  PeerConnectionJsepTest() {
    network_thread_ = Thread::CreateWithSocketServer();
    network_thread_->SetName("NetworkThread", nullptr);
    EXPECT_TRUE(network_thread_->Start());
#ifdef WEBRTC_ANDROID
    InitializeAndroidObjects();
#endif
  }

  PeerConnectionFactoryDependencies CreatePeerConnectionFactoryDependencies() {
    PeerConnectionFactoryDependencies dependencies;
    dependencies.network_thread = network_thread_.get();
    dependencies.signaling_thread = Thread::Current();
    dependencies.adm = FakeAudioCaptureModule::Create();
    dependencies.env = CreateTestEnvironment();
    EnableMediaWithDefaults(dependencies);
    dependencies.sctp_factory = std::make_unique<FakeSctpTransportFactory>();
    return dependencies;
  }

  WrapperPtr CreatePeerConnection() {
    RTCConfiguration config;
    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
    return CreatePeerConnection(config);
  }

  WrapperPtr CreatePeerConnection(absl::string_view field_trials) {
    RTCConfiguration config;
    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
    return CreatePeerConnection(config, field_trials);
  }

  WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
    return CreatePeerConnection(config, "");
  }

  WrapperPtr CreatePeerConnection(const RTCConfiguration& config,
                                  absl::string_view field_trials) {
    scoped_refptr<PeerConnectionFactoryInterface> pc_factory =
        CreateModularPeerConnectionFactory(
            CreatePeerConnectionFactoryDependencies());
    auto observer = std::make_unique<MockPeerConnectionObserver>();
    PeerConnectionDependencies pc_deps(observer.get());
    if (!field_trials.empty()) {
      pc_deps.trials = CreateTestFieldTrialsPtr(field_trials);
    }
    auto result =
        pc_factory->CreatePeerConnectionOrError(config, std::move(pc_deps));
    if (!result.ok()) {
      return nullptr;
    }

    observer->SetPeerConnectionInterface(result.value().get());
    return std::make_unique<PeerConnectionWrapper>(
        pc_factory, result.MoveValue(), std::move(observer));
  }

  test::RunLoop run_loop_;
  std::unique_ptr<Thread> network_thread_;
};

// Tests for JSEP initial offer generation.

// Test that an offer created by a PeerConnection with no transceivers generates
// no media sections.
TEST_F(PeerConnectionJsepTest, EmptyInitialOffer) {
  auto caller = CreatePeerConnection();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ASSERT_EQ(0u, offer->description()->contents().size());
}

// Test that an initial offer with one audio track generates one audio media
// section.
TEST_F(PeerConnectionJsepTest, AudioOnlyInitialOffer) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_EQ(MediaType::AUDIO, contents[0].media_description()->type());
}

// Test than an initial offer with one video track generates one video media
// section
TEST_F(PeerConnectionJsepTest, VideoOnlyInitialOffer) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::VIDEO);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_EQ(MediaType::VIDEO, contents[0].media_description()->type());
}

// Test that an initial offer with one data channel generates one data media
// section.
TEST_F(PeerConnectionJsepTest, DataOnlyInitialOffer) {
  auto caller = CreatePeerConnection();
  caller->CreateDataChannel("dc");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_EQ(MediaType::DATA, contents[0].media_description()->type());
}

// Test that creating multiple data channels only results in one data section
// generated in the offer.
TEST_F(PeerConnectionJsepTest, MultipleDataChannelsCreateOnlyOneDataSection) {
  auto caller = CreatePeerConnection();
  caller->CreateDataChannel("first");
  caller->CreateDataChannel("second");
  caller->CreateDataChannel("third");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ASSERT_EQ(1u, offer->description()->contents().size());
}

// Test that multiple media sections in the initial offer are ordered in the
// order the transceivers were added to the PeerConnection. This is required by
// JSEP section 5.2.1.
TEST_F(PeerConnectionJsepTest, MediaSectionsInInitialOfferOrderedCorrectly) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::VIDEO);
  caller->AddTransceiver(MediaType::AUDIO);
  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  caller->AddTransceiver(MediaType::VIDEO, init);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(3u, contents.size());

  const MediaContentDescription* media_description1 =
      contents[0].media_description();
  EXPECT_EQ(MediaType::VIDEO, media_description1->type());
  EXPECT_EQ(RtpTransceiverDirection::kSendRecv,
            media_description1->direction());

  const MediaContentDescription* media_description2 =
      contents[1].media_description();
  EXPECT_EQ(MediaType::AUDIO, media_description2->type());
  EXPECT_EQ(RtpTransceiverDirection::kSendRecv,
            media_description2->direction());

  const MediaContentDescription* media_description3 =
      contents[2].media_description();
  EXPECT_EQ(MediaType::VIDEO, media_description3->type());
  EXPECT_EQ(RtpTransceiverDirection::kSendOnly,
            media_description3->direction());
}

// Test that media sections in the initial offer have different mids.
TEST_F(PeerConnectionJsepTest, MediaSectionsInInitialOfferHaveDifferentMids) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  caller->AddTransceiver(MediaType::AUDIO);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(2u, contents.size());
  EXPECT_NE(contents[0].mid(), contents[1].mid());
}

TEST_F(PeerConnectionJsepTest,
       StoppedTransceiverHasNoMediaSectionInInitialOffer) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  transceiver->StopInternal();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  EXPECT_EQ(0u, offer->description()->contents().size());
}

// Tests for JSEP SetLocalDescription with a local offer.

TEST_F(PeerConnectionJsepTest, SetLocalEmptyOfferCreatesNoTransceivers) {
  auto caller = CreatePeerConnection();

  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));

  EXPECT_THAT(caller->pc()->GetTransceivers(), ElementsAre());
  EXPECT_THAT(caller->pc()->GetSenders(), ElementsAre());
  EXPECT_THAT(caller->pc()->GetReceivers(), ElementsAre());
}

TEST_F(PeerConnectionJsepTest, SetLocalOfferSetsTransceiverMid) {
  auto caller = CreatePeerConnection();
  auto audio_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto video_transceiver = caller->AddTransceiver(MediaType::VIDEO);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto audio_mid = offer->description()->contents()[0].mid();
  auto video_mid = offer->description()->contents()[1].mid();

  ASSERT_TRUE(caller->SetLocalDescription(std::move(offer)));

  EXPECT_EQ(audio_mid, audio_transceiver->mid());
  EXPECT_EQ(video_mid, video_transceiver->mid());
}

// Tests for JSEP SetRemoteDescription with a remote offer.

// Test that setting a remote offer with sendrecv audio and video creates two
// transceivers, one for receiving audio and one for receiving video.
TEST_F(PeerConnectionJsepTest, SetRemoteOfferCreatesTransceivers) {
  auto caller = CreatePeerConnection();
  auto caller_audio = caller->AddTransceiver(MediaType::AUDIO);
  auto caller_video = caller->AddTransceiver(MediaType::VIDEO);
  auto callee = CreatePeerConnection();

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

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

  EXPECT_EQ(MediaType::AUDIO, transceivers[0]->media_type());
  EXPECT_EQ(caller_audio->mid(), transceivers[0]->mid());
  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceivers[0]->direction());
  EXPECT_EQ(0u, transceivers[0]->sender()->stream_ids().size());

  EXPECT_EQ(MediaType::VIDEO, transceivers[1]->media_type());
  EXPECT_EQ(caller_video->mid(), transceivers[1]->mid());
  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceivers[1]->direction());
  EXPECT_EQ(0u, transceivers[1]->sender()->stream_ids().size());
}

// Test that setting a remote offer with an audio track will reuse the
// transceiver created for a local audio track added by AddTrack.
// This is specified in JSEP section 5.10 (Applying a Remote Description). The
// intent is to preserve backwards compatibility with clients who only use the
// AddTrack API.
TEST_F(PeerConnectionJsepTest, SetRemoteOfferReusesTransceiverFromAddTrack) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto caller_audio = caller->pc()->GetTransceivers()[0];
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, transceivers.size());
  EXPECT_EQ(MediaStreamTrackInterface::kAudioKind,
            transceivers[0]->receiver()->track()->kind());
  EXPECT_EQ(caller_audio->mid(), transceivers[0]->mid());
}

// Test that setting a remote offer with an audio track marked sendonly will not
// reuse a transceiver created by AddTrack. JSEP only allows the transceiver to
// be reused if the offer direction is sendrecv or recvonly.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferDoesNotReuseTransceiverIfDirectionSendOnly) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto caller_audio = caller->pc()->GetTransceivers()[0];
  caller_audio->SetDirectionWithError(RtpTransceiverDirection::kSendOnly);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
  EXPECT_EQ(caller_audio->mid(), transceivers[1]->mid());
}

// Test that setting a remote offer with an audio track will not reuse a
// transceiver added by AddTransceiver. The logic for reusing a transceiver is
// specific to those added by AddTrack and is tested above.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferDoesNotReuseTransceiverFromAddTransceiver) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  auto transceiver = callee->AddTransceiver(MediaType::AUDIO);

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
  EXPECT_EQ(caller->pc()->GetTransceivers()[0]->mid(), transceivers[1]->mid());
  EXPECT_EQ(MediaStreamTrackInterface::kAudioKind,
            transceivers[1]->receiver()->track()->kind());
}

// Test that setting a remote offer with an audio track will not reuse a
// transceiver created for a local video track added by AddTrack.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferDoesNotReuseTransceiverOfWrongType) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  auto video_sender = callee->AddVideoTrack("v");

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
  EXPECT_EQ(caller->pc()->GetTransceivers()[0]->mid(), transceivers[1]->mid());
  EXPECT_EQ(MediaStreamTrackInterface::kAudioKind,
            transceivers[1]->receiver()->track()->kind());
}

// Test that setting a remote offer with an audio track will not reuse a
// stopped transceiver.
TEST_F(PeerConnectionJsepTest, SetRemoteOfferDoesNotReuseStoppedTransceiver) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  callee->pc()->GetTransceivers()[0]->StopInternal();

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, transceivers.size());
  // The stopped transceiver is removed in SetLocalDescription(answer)
  ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
  transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, transceivers.size());
  EXPECT_EQ(caller->pc()->GetTransceivers()[0]->mid(), transceivers[0]->mid());
  EXPECT_FALSE(transceivers[0]->stopped());
}

// Test that audio and video transceivers created on the remote side with
// AddTrack will all be reused if there is the same number of audio/video tracks
// in the remote offer. Additionally, this tests that transceivers are
// successfully matched even if they are in a different order on the remote
// side.
TEST_F(PeerConnectionJsepTest, SetRemoteOfferReusesTransceiversOfBothTypes) {
  auto caller = CreatePeerConnection();
  caller->AddVideoTrack("v");
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  callee->AddVideoTrack("v");

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

  auto caller_transceivers = caller->pc()->GetTransceivers();
  auto callee_transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(2u, callee_transceivers.size());
  EXPECT_EQ(caller_transceivers[0]->mid(), callee_transceivers[1]->mid());
  EXPECT_EQ(caller_transceivers[1]->mid(), callee_transceivers[0]->mid());
}

// Tests for JSEP initial CreateAnswer.

// Test that the answer to a remote offer creates media sections for each
// offered media in the same order and with the same mids.
TEST_F(PeerConnectionJsepTest, CreateAnswerHasSameMidsAsOffer) {
  auto caller = CreatePeerConnection();
  auto first_transceiver = caller->AddTransceiver(MediaType::VIDEO);
  auto second_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto third_transceiver = caller->AddTransceiver(MediaType::VIDEO);
  caller->CreateDataChannel("dc");
  auto callee = CreatePeerConnection();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  const auto* offer_data = GetFirstDataContent(offer->description());
  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto contents = answer->description()->contents();
  ASSERT_EQ(4u, contents.size());
  EXPECT_EQ(MediaType::VIDEO, contents[0].media_description()->type());
  EXPECT_EQ(first_transceiver->mid(), contents[0].mid());
  EXPECT_EQ(MediaType::AUDIO, contents[1].media_description()->type());
  EXPECT_EQ(second_transceiver->mid(), contents[1].mid());
  EXPECT_EQ(MediaType::VIDEO, contents[2].media_description()->type());
  EXPECT_EQ(third_transceiver->mid(), contents[2].mid());
  EXPECT_EQ(MediaType::DATA, contents[3].media_description()->type());
  EXPECT_EQ(offer_data->mid(), contents[3].mid());
}

// Test that an answering media section is marked as rejected if the underlying
// transceiver has been stopped.
TEST_F(PeerConnectionJsepTest, CreateAnswerRejectsStoppedTransceiver) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();

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

  callee->pc()->GetTransceivers()[0]->StopInternal();

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto contents = answer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_TRUE(contents[0].rejected);
}

// Test that CreateAnswer will generate media sections which will only send or
// receive if the offer indicates it can do the reciprocating direction.
// The full matrix is tested more extensively in MediaSession.
TEST_F(PeerConnectionJsepTest, CreateAnswerNegotiatesDirection) {
  auto caller = CreatePeerConnection();
  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  caller->AddTransceiver(MediaType::AUDIO, init);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");

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

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto contents = answer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly,
            contents[0].media_description()->direction());
}

// Tests for JSEP SetLocalDescription with a local answer.
// Note that these test only the additional behaviors not covered by
// SetLocalDescription with a local offer.

// Test that SetLocalDescription with an answer sets the current_direction
// property of the transceivers mentioned in the session description.
TEST_F(PeerConnectionJsepTest, SetLocalAnswerUpdatesCurrentDirection) {
  auto caller = CreatePeerConnection();
  auto caller_audio = caller->AddTransceiver(MediaType::AUDIO);
  caller_audio->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");

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

  auto transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, transceivers.size());
  // Since the offer was recvonly and the transceiver direction is sendrecv,
  // the negotiated direction will be sendonly.
  EXPECT_EQ(RtpTransceiverDirection::kSendOnly,
            transceivers[0]->current_direction());
}

// Tests for JSEP SetRemoteDescription with a remote answer.
// Note that these test only the additional behaviors not covered by
// SetRemoteDescription with a remote offer.

TEST_F(PeerConnectionJsepTest, SetRemoteAnswerUpdatesCurrentDirection) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  auto callee_audio = callee->pc()->GetTransceivers()[0];
  callee_audio->SetDirectionWithError(RtpTransceiverDirection::kSendOnly);

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

  auto transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(1u, transceivers.size());
  // Since the remote transceiver was set to sendonly, the negotiated direction
  // in the answer would be sendonly which we apply as recvonly to the local
  // transceiver.
  EXPECT_EQ(RtpTransceiverDirection::kRecvOnly,
            transceivers[0]->current_direction());
}

TEST_F(PeerConnectionJsepTest,
       ChangeDirectionFromRecvOnlyToSendRecvDoesNotBreakVideoNegotiation) {
  auto caller = CreatePeerConnection();
  auto caller_transceiver = caller->AddTransceiver(MediaType::VIDEO);
  auto callee = CreatePeerConnection();
  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly);

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

  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);

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

TEST_F(PeerConnectionJsepTest,
       ChangeDirectionFromRecvOnlyToSendRecvDoesNotBreakAudioNegotiation) {
  auto caller = CreatePeerConnection();
  auto caller_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly);

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

  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);

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

// Tests for multiple round trips.

// Test that setting a transceiver with the inactive direction does not stop it
// on either the caller or the callee.
TEST_F(PeerConnectionJsepTest, SettingTransceiverInactiveDoesNotStopIt) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  callee->pc()->GetTransceivers()[0]->SetDirectionWithError(
      RtpTransceiverDirection::kInactive);

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

  EXPECT_FALSE(caller->pc()->GetTransceivers()[0]->stopped());
  EXPECT_FALSE(callee->pc()->GetTransceivers()[0]->stopped());
}

// Test that if a transceiver had been associated and later stopped, then a
// media section is still generated for it and the media section is marked as
// rejected.
TEST_F(PeerConnectionJsepTest,
       ReOfferMediaSectionForAssociatedStoppedTransceiverIsRejected) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

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

  ASSERT_TRUE(transceiver->mid());
  transceiver->StopInternal();

  auto reoffer = caller->CreateOffer();
  auto contents = reoffer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  EXPECT_TRUE(contents[0].rejected);
}

// Test that stopping an associated transceiver on the caller side will stop the
// corresponding transceiver on the remote side when the remote offer is
// applied.
TEST_F(PeerConnectionJsepTest,
       StoppingTransceiverInOfferStopsTransceiverOnRemoteSide) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

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

  transceiver->StopInternal();

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

  auto transceivers = callee->pc()->GetTransceivers();
  EXPECT_EQ(1u, transceivers.size());
  ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
  transceivers = callee->pc()->GetTransceivers();
  EXPECT_EQ(0u, transceivers.size());
}

// Test that CreateOffer will only generate a recycled media section if the
// transceiver to be recycled has been seen stopped by the other side first.
TEST_F(PeerConnectionJsepTest,
       CreateOfferDoesNotRecycleMediaSectionIfFirstStopped) {
  auto caller = CreatePeerConnection();
  auto first_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

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

  auto second_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  first_transceiver->StopInternal();

  auto reoffer = caller->CreateOffer();
  auto contents = reoffer->description()->contents();
  ASSERT_EQ(2u, contents.size());
  EXPECT_TRUE(contents[0].rejected);
  EXPECT_FALSE(contents[1].rejected);
}

// Test that the offer/answer and the transceivers are correctly generated and
// updated when the media section is recycled after the callee stops a
// transceiver and sends an answer with a 0 port.
TEST_F(PeerConnectionJsepTest,
       RecycleMediaSectionWhenStoppingTransceiverOnAnswerer) {
  auto caller = CreatePeerConnection();
  auto first_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  std::string first_mid = *first_transceiver->mid();
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  callee->pc()->GetTransceivers()[0]->StopInternal();
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
  EXPECT_TRUE(first_transceiver->stopped());
  // First transceivers are dissociated on caller side.
  ASSERT_EQ(std::nullopt, first_transceiver->mid());
  // They are disassociated on callee side.
  ASSERT_EQ(0u, callee->pc()->GetTransceivers().size());

  // New offer exchange with new transceivers that recycles the m section
  // correctly.
  caller->AddAudioTrack("audio2");
  callee->AddAudioTrack("audio2");
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto offer_contents = offer->description()->contents();
  auto second_mid = offer_contents[0].mid();
  ASSERT_EQ(1u, offer_contents.size());
  EXPECT_FALSE(offer_contents[0].rejected);
  EXPECT_NE(first_mid, second_mid);

  // Setting the offer on each side will dissociate the first transceivers and
  // associate the new transceivers.
  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  EXPECT_EQ(std::nullopt, first_transceiver->mid());
  ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
  EXPECT_EQ(second_mid, caller->pc()->GetTransceivers()[0]->mid());
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  EXPECT_EQ(second_mid, callee->pc()->GetTransceivers()[0]->mid());

  // The new answer should also recycle the m section correctly.
  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(1u, answer_contents.size());
  EXPECT_FALSE(answer_contents[0].rejected);
  EXPECT_EQ(second_mid, answer_contents[0].mid());

  // Finishing the negotiation shouldn't add or dissociate any transceivers.
  ASSERT_TRUE(callee->SetLocalDescription(answer->Clone()));
  ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
  auto caller_transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(1u, caller_transceivers.size());
  EXPECT_EQ(second_mid, caller_transceivers[0]->mid());
  auto callee_transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, callee_transceivers.size());
  EXPECT_EQ(second_mid, callee_transceivers[0]->mid());
}

// Test that creating/setting a local offer that recycles an m= section is
// idempotent.
TEST_F(PeerConnectionJsepTest, CreateOfferRecyclesWhenOfferingTwice) {
  // Do a negotiation with a port 0 for the media section.
  auto caller = CreatePeerConnection();
  auto first_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
  first_transceiver->StopInternal();
  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
  caller->AddAudioTrack("audio2");

  // Create a new offer that recycles the media section and set it as a local
  // description.
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  EXPECT_FALSE(offer_contents[0].rejected);
  ASSERT_TRUE(caller->SetLocalDescription(std::move(offer)));
  ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
  EXPECT_FALSE(caller->pc()->GetTransceivers()[0]->stopped());
  auto second_mid = offer_contents[0].mid();

  // Create another new offer and set the local description again without the
  // rest of any negotation ocurring.
  auto second_offer = caller->CreateOffer();
  auto second_offer_contents = second_offer->description()->contents();
  ASSERT_EQ(1u, second_offer_contents.size());
  EXPECT_FALSE(second_offer_contents[0].rejected);
  // The mid shouldn't change.
  EXPECT_EQ(second_mid, second_offer_contents[0].mid());

  ASSERT_TRUE(caller->SetLocalDescription(std::move(second_offer)));
  // Make sure that the caller's transceivers are associated correctly.
  auto caller_transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(1u, caller_transceivers.size());
  EXPECT_EQ(second_mid, caller_transceivers[0]->mid());
  EXPECT_FALSE(caller_transceivers[0]->stopped());
}

// Test that the offer/answer and transceivers for both the caller and callee
// side are generated/updated correctly when recycling an audio/video media
// section as a media section of either the same or opposite type.
// Correct recycling works as follows:
// - The m= section is re-offered with a new MID value and the new media type.
// - The previously-associated transceiver is dissociated when the new offer is
//   set as a local description on the offerer or as a remote description on
//   the answerer.
// - The new transceiver is associated with the new MID value.
class RecycleMediaSectionTest
    : public PeerConnectionJsepTest,
      public ::testing::WithParamInterface<std::tuple<MediaType, MediaType>> {
 protected:
  RecycleMediaSectionTest() {
    first_type_ = std::get<0>(GetParam());
    second_type_ = std::get<1>(GetParam());
  }

  MediaType first_type_;
  MediaType second_type_;
};

// Test that recycling works properly when a new transceiver recycles an m=
// section that was rejected in both the current local and remote descriptions.
TEST_P(RecycleMediaSectionTest, CurrentLocalAndCurrentRemoteRejected) {
  auto caller = CreatePeerConnection();
  auto first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  auto first_mid = *first_transceiver->mid();
  first_transceiver->StopInternal();

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

  auto second_transceiver = caller->AddTransceiver(second_type_);

  // The offer should reuse the previous media section but allocate a new MID
  // and change the media type.
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  EXPECT_FALSE(offer_contents[0].rejected);
  EXPECT_EQ(second_type_, offer_contents[0].media_description()->type());
  auto second_mid = offer_contents[0].mid();
  EXPECT_NE(first_mid, second_mid);

  // Setting the local offer will dissociate the previous transceiver and set
  // the MID for the new transceiver.
  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  EXPECT_EQ(std::nullopt, first_transceiver->mid());
  EXPECT_EQ(second_mid, second_transceiver->mid());

  // Setting the remote offer will dissociate the previous transceiver and
  // create a new transceiver for the media section.
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  auto callee_transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, callee_transceivers.size());
  EXPECT_EQ(second_mid, callee_transceivers[0]->mid());
  EXPECT_EQ(second_type_, callee_transceivers[0]->media_type());

  // The answer should have only one media section for the new transceiver.
  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(1u, answer_contents.size());
  EXPECT_FALSE(answer_contents[0].rejected);
  EXPECT_EQ(second_mid, answer_contents[0].mid());
  EXPECT_EQ(second_type_, answer_contents[0].media_description()->type());

  // Setting the local answer should succeed.
  ASSERT_TRUE(callee->SetLocalDescription(answer->Clone()));

  // Setting the remote answer should succeed and not create any new
  // transceivers.
  ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
  ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
}

// Test that recycling works properly when a new transceiver recycles an m=
// section that was rejected in only the current remote description.
TEST_P(RecycleMediaSectionTest, CurrentRemoteOnlyRejected) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  std::string first_mid = *caller_first_transceiver->mid();
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  auto callee_first_transceiver = callee->pc()->GetTransceivers()[0];
  callee_first_transceiver->StopInternal();

  // The answer will have a rejected m= section.
  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  // The offer should reuse the previous media section but allocate a new MID
  // and change the media type.
  auto caller_second_transceiver = caller->AddTransceiver(second_type_);
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  const auto& offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  EXPECT_FALSE(offer_contents[0].rejected);
  EXPECT_EQ(second_type_, offer_contents[0].media_description()->type());
  auto second_mid = offer_contents[0].mid();
  EXPECT_NE(first_mid, second_mid);

  // Setting the local offer will dissociate the previous transceiver and set
  // the MID for the new transceiver.
  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  EXPECT_EQ(std::nullopt, caller_first_transceiver->mid());
  EXPECT_EQ(second_mid, caller_second_transceiver->mid());

  // Setting the remote offer will dissociate the previous transceiver and
  // create a new transceiver for the media section.
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  auto callee_transceivers = callee->pc()->GetTransceivers();
  ASSERT_EQ(1u, callee_transceivers.size());
  EXPECT_EQ(second_mid, callee_transceivers[0]->mid());
  EXPECT_EQ(second_type_, callee_transceivers[0]->media_type());

  // The answer should have only one media section for the new transceiver.
  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(1u, answer_contents.size());
  EXPECT_FALSE(answer_contents[0].rejected);
  EXPECT_EQ(second_mid, answer_contents[0].mid());
  EXPECT_EQ(second_type_, answer_contents[0].media_description()->type());

  // Setting the local answer should succeed.
  ASSERT_TRUE(callee->SetLocalDescription(answer->Clone()));

  // Setting the remote answer should succeed and not create any new
  // transceivers.
  ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
  ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
}

// Test that recycling works properly when a new transceiver recycles an m=
// section that was rejected only in the current local description.
TEST_P(RecycleMediaSectionTest, CurrentLocalOnlyRejected) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  std::string first_mid = *caller_first_transceiver->mid();
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  auto callee_first_transceiver = callee->pc()->GetTransceivers()[0];
  callee_first_transceiver->StopInternal();

  // The answer will have a rejected m= section.
  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  // The offer should reuse the previous media section but allocate a new MID
  // and change the media type.
  auto callee_second_transceiver = callee->AddTransceiver(second_type_);
  std::unique_ptr<SessionDescriptionInterface> offer = callee->CreateOffer();
  const auto& offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  EXPECT_FALSE(offer_contents[0].rejected);
  EXPECT_EQ(second_type_, offer_contents[0].media_description()->type());
  auto second_mid = offer_contents[0].mid();
  EXPECT_NE(first_mid, second_mid);

  // Setting the local offer will dissociate the previous transceiver and set
  // the MID for the new transceiver.
  ASSERT_TRUE(callee->SetLocalDescription(offer->Clone()));
  EXPECT_EQ(std::nullopt, callee_first_transceiver->mid());
  EXPECT_EQ(second_mid, callee_second_transceiver->mid());

  // Setting the remote offer will dissociate the previous transceiver and
  // create a new transceiver for the media section.
  ASSERT_TRUE(caller->SetRemoteDescription(std::move(offer)));
  auto caller_transceivers = caller->pc()->GetTransceivers();
  ASSERT_EQ(1u, caller_transceivers.size());
  EXPECT_EQ(second_mid, caller_transceivers[0]->mid());
  EXPECT_EQ(second_type_, caller_transceivers[0]->media_type());

  // The answer should have only one media section for the new transceiver.
  std::unique_ptr<SessionDescriptionInterface> answer = caller->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(1u, answer_contents.size());
  EXPECT_FALSE(answer_contents[0].rejected);
  EXPECT_EQ(second_mid, answer_contents[0].mid());
  EXPECT_EQ(second_type_, answer_contents[0].media_description()->type());

  // Setting the local answer should succeed.
  ASSERT_TRUE(caller->SetLocalDescription(answer->Clone()));

  // Setting the remote answer should succeed and not create any new
  // transceivers.
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(answer)));
  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
}

// Test that a m= section is *not* recycled if the media section is only
// rejected in the pending local description and there is no current remote
// description.
TEST_P(RecycleMediaSectionTest, PendingLocalRejectedAndNoRemote) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);

  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));

  auto first_mid = *caller_first_transceiver->mid();
  caller_first_transceiver->StopInternal();

  // The reoffer will have a rejected m= section.
  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));

  auto caller_second_transceiver = caller->AddTransceiver(second_type_);

  // The reoffer should not recycle the existing m= section since it is not
  // rejected in either the *current* local or *current* remote description.
  auto reoffer = caller->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  ASSERT_EQ(2u, reoffer_contents.size());
  EXPECT_TRUE(reoffer_contents[0].rejected);
  EXPECT_EQ(first_type_, reoffer_contents[0].media_description()->type());
  EXPECT_EQ(first_mid, reoffer_contents[0].mid());
  EXPECT_FALSE(reoffer_contents[1].rejected);
  EXPECT_EQ(second_type_, reoffer_contents[1].media_description()->type());
  auto second_mid = reoffer_contents[1].mid();
  EXPECT_NE(first_mid, second_mid);

  ASSERT_TRUE(caller->SetLocalDescription(std::move(reoffer)));

  // Both RtpTransceivers are associated.
  EXPECT_EQ(first_mid, caller_first_transceiver->mid());
  EXPECT_EQ(second_mid, caller_second_transceiver->mid());
}

// Test that a m= section is *not* recycled if the media section is only
// rejected in the pending local description and not rejected in the current
// remote description.
TEST_P(RecycleMediaSectionTest, PendingLocalRejectedAndNotRejectedRemote) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  auto first_mid = *caller_first_transceiver->mid();
  caller_first_transceiver->StopInternal();

  // The reoffer will have a rejected m= section.
  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));

  auto caller_second_transceiver = caller->AddTransceiver(second_type_);

  // The reoffer should not recycle the existing m= section since it is not
  // rejected in either the *current* local or *current* remote description.
  auto reoffer = caller->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  ASSERT_EQ(2u, reoffer_contents.size());
  EXPECT_TRUE(reoffer_contents[0].rejected);
  EXPECT_EQ(first_type_, reoffer_contents[0].media_description()->type());
  EXPECT_EQ(first_mid, reoffer_contents[0].mid());
  EXPECT_FALSE(reoffer_contents[1].rejected);
  EXPECT_EQ(second_type_, reoffer_contents[1].media_description()->type());
  auto second_mid = reoffer_contents[1].mid();
  EXPECT_NE(first_mid, second_mid);

  ASSERT_TRUE(caller->SetLocalDescription(std::move(reoffer)));

  // Both RtpTransceivers are associated.
  EXPECT_EQ(first_mid, caller_first_transceiver->mid());
  EXPECT_EQ(second_mid, caller_second_transceiver->mid());
}

TEST_F(PeerConnectionJsepTest, LocallyRejectedTransceiverDoesNotCrash) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);

  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));

  transceiver->StopInternal();

  // The reoffer will have a rejected media section.
  // Setting it as local description triggers
  // MaybeHandleLocallyRejectedTransceiver.
  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
}

// Test that an m= section is *not* recycled if the media section is only
// rejected in the pending remote description and there is no current local
// description.
TEST_P(RecycleMediaSectionTest, PendingRemoteRejectedAndNoLocal) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  auto callee_first_transceiver = callee->pc()->GetTransceivers()[0];
  std::string first_mid = *callee_first_transceiver->mid();
  caller_first_transceiver->StopInternal();

  // The reoffer will have a rejected m= section.
  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto callee_second_transceiver = callee->AddTransceiver(second_type_);

  // The reoffer should not recycle the existing m= section since it is not
  // rejected in either the *current* local or *current* remote description.
  auto reoffer = callee->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  ASSERT_EQ(2u, reoffer_contents.size());
  EXPECT_TRUE(reoffer_contents[0].rejected);
  EXPECT_EQ(first_type_, reoffer_contents[0].media_description()->type());
  EXPECT_EQ(first_mid, reoffer_contents[0].mid());
  EXPECT_FALSE(reoffer_contents[1].rejected);
  EXPECT_EQ(second_type_, reoffer_contents[1].media_description()->type());
  auto second_mid = reoffer_contents[1].mid();
  EXPECT_NE(first_mid, second_mid);

  // Note: Cannot actually set the reoffer since the callee is in the signaling
  // state 'have-remote-offer'.
}

// Test that an m= section is *not* recycled if the media section is only
// rejected in the pending remote description and not rejected in the current
// local description.
TEST_P(RecycleMediaSectionTest, PendingRemoteRejectedAndNotRejectedLocal) {
  auto caller = CreatePeerConnection();
  auto caller_first_transceiver = caller->AddTransceiver(first_type_);
  auto callee = CreatePeerConnection();

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

  ASSERT_EQ(1u, callee->pc()->GetTransceivers().size());
  auto callee_first_transceiver = callee->pc()->GetTransceivers()[0];
  std::string first_mid = *callee_first_transceiver->mid();
  caller_first_transceiver->StopInternal();

  // The reoffer will have a rejected m= section.
  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto callee_second_transceiver = callee->AddTransceiver(second_type_);

  // The reoffer should not recycle the existing m= section since it is not
  // rejected in either the *current* local or *current* remote description.
  auto reoffer = callee->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  ASSERT_EQ(2u, reoffer_contents.size());
  EXPECT_TRUE(reoffer_contents[0].rejected);
  EXPECT_EQ(first_type_, reoffer_contents[0].media_description()->type());
  EXPECT_EQ(first_mid, reoffer_contents[0].mid());
  EXPECT_FALSE(reoffer_contents[1].rejected);
  EXPECT_EQ(second_type_, reoffer_contents[1].media_description()->type());
  auto second_mid = reoffer_contents[1].mid();
  EXPECT_NE(first_mid, second_mid);

  // Note: Cannot actually set the reoffer since the callee is in the signaling
  // state 'have-remote-offer'.
}

// Test all combinations of audio and video as the first and second media type
// for the media section. This is needed for full test coverage because
// MediaSession has separate functions for processing audio and video media
// sections.
INSTANTIATE_TEST_SUITE_P(PeerConnectionJsepTest,
                         RecycleMediaSectionTest,
                         Combine(Values(MediaType::AUDIO, MediaType::VIDEO),
                                 Values(MediaType::AUDIO, MediaType::VIDEO)));

// Test that a new data channel section will not reuse a recycleable audio or
// video media section. Additionally, tests that the new section is added to the
// end of the session description.
TEST_F(PeerConnectionJsepTest, DataChannelDoesNotRecycleMediaSection) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

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

  transceiver->StopInternal();

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

  caller->CreateDataChannel("dc");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto offer_contents = offer->description()->contents();
  ASSERT_EQ(2u, offer_contents.size());
  EXPECT_EQ(MediaType::AUDIO, offer_contents[0].media_description()->type());
  EXPECT_EQ(MediaType::DATA, offer_contents[1].media_description()->type());

  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(2u, answer_contents.size());
  EXPECT_EQ(MediaType::AUDIO, answer_contents[0].media_description()->type());
  EXPECT_EQ(MediaType::DATA, answer_contents[1].media_description()->type());
}

// Test that if a new track is added to an existing session that has a data,
// the new section comes at the end of the new offer, after the existing data
// section.
TEST_F(PeerConnectionJsepTest, AudioTrackAddedAfterDataSectionInReoffer) {
  auto caller = CreatePeerConnection();
  caller->CreateDataChannel("dc");
  auto callee = CreatePeerConnection();

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

  caller->AddAudioTrack("a");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(2u, contents.size());
  EXPECT_EQ(MediaType::DATA, contents[0].media_description()->type());
  EXPECT_EQ(MediaType::AUDIO, contents[1].media_description()->type());
}

// Tests for MID properties.

static void RenameSection(size_t mline_index,
                          absl::string_view new_mid,
                          SessionDescriptionInterface* sdesc) {
  SessionDescription* desc = sdesc->description();
  std::string old_mid(desc->contents()[mline_index].mid());
  desc->contents()[mline_index].set_mid(new_mid);
  desc->transport_infos()[mline_index].content_name = new_mid;
  const ContentGroup* bundle = desc->GetGroupByName(GROUP_TYPE_BUNDLE);
  if (bundle) {
    ContentGroup new_bundle = *bundle;
    if (new_bundle.RemoveContentName(old_mid)) {
      new_bundle.AddContentName(new_mid);
    }
    desc->RemoveGroupByName(GROUP_TYPE_BUNDLE);
    desc->AddGroup(new_bundle);
  }
}

// Test that two PeerConnections can have a successful offer/answer exchange if
// the MIDs are changed from the defaults.
TEST_F(PeerConnectionJsepTest, OfferAnswerWithChangedMids) {
  constexpr char kFirstMid[] = "nondefaultmid";
  constexpr char kSecondMid[] = "randommid";

  // Munging allowed: kMid (25)
  auto caller =
      CreatePeerConnection("WebRTC-NoSdpMangleAllowForTesting/Enabled,25/");
  caller->AddAudioTrack("a");
  caller->AddAudioTrack("b");
  auto callee = CreatePeerConnection();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  RenameSection(0, kFirstMid, offer.get());
  RenameSection(1, kSecondMid, offer.get());

  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  auto caller_transceivers = caller->pc()->GetTransceivers();
  EXPECT_EQ(kFirstMid, caller_transceivers[0]->mid());
  EXPECT_EQ(kSecondMid, caller_transceivers[1]->mid());

  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  auto callee_transceivers = callee->pc()->GetTransceivers();
  EXPECT_EQ(kFirstMid, callee_transceivers[0]->mid());
  EXPECT_EQ(kSecondMid, callee_transceivers[1]->mid());

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto answer_contents = answer->description()->contents();
  EXPECT_EQ(kFirstMid, answer_contents[0].mid());
  EXPECT_EQ(kSecondMid, answer_contents[1].mid());

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

// Test that CreateOffer will generate a MID that is not already used if the
// default it would have picked is already taken. This is tested by using a
// third PeerConnection to determine what the default would be for the second
// media section then setting that as the first media section's MID.
TEST_F(PeerConnectionJsepTest, CreateOfferGeneratesUniqueMidIfAlreadyTaken) {
  // First, find what the default MID is for the second media section.
  auto pc = CreatePeerConnection();
  pc->AddAudioTrack("a");
  pc->AddAudioTrack("b");
  auto default_offer = pc->CreateOffer();
  auto default_second_mid = default_offer->description()->contents()[1].mid();

  // Now, do an offer/answer with one track which has the MID set to the default
  // second MID.
  // Munging allowed: kMid (25)
  auto caller =
      CreatePeerConnection("WebRTC-NoSdpMangleAllowForTesting/Enabled,25/");
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  RenameSection(0, default_second_mid, offer.get());

  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  // Add a second track and ensure that the MID is different.
  caller->AddAudioTrack("b");

  auto reoffer = caller->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  EXPECT_EQ(default_second_mid, reoffer_contents[0].mid());
  EXPECT_NE(reoffer_contents[0].mid(), reoffer_contents[1].mid());
}

// Test that if an audio or video section has the default data section MID, then
// CreateOffer will generate a unique MID for the newly added data section.
TEST_F(PeerConnectionJsepTest,
       CreateOfferGeneratesUniqueMidForDataSectionIfAlreadyTaken) {
  // First, find what the default MID is for the data channel.
  auto pc = CreatePeerConnection();
  pc->CreateDataChannel("dc");
  auto default_offer = pc->CreateOffer();
  auto default_data_mid = default_offer->description()->contents()[0].mid();

  // Now do an offer/answer with one audio track which has a MID set to the
  // default data MID.
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  RenameSection(0, default_data_mid, offer.get());

  ASSERT_TRUE(caller->SetLocalDescription(offer->Clone()));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  // Add a data channel and ensure that the MID is different.
  caller->CreateDataChannel("dc");

  auto reoffer = caller->CreateOffer();
  auto reoffer_contents = reoffer->description()->contents();
  EXPECT_EQ(default_data_mid, reoffer_contents[0].mid());
  EXPECT_NE(reoffer_contents[0].mid(), reoffer_contents[1].mid());
}

// Test that a reoffer initiated by the callee adds a new track to the caller.
TEST_F(PeerConnectionJsepTest, CalleeDoesReoffer) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  callee->AddVideoTrack("v");

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

  EXPECT_EQ(1u, caller->pc()->GetTransceivers().size());
  EXPECT_EQ(2u, callee->pc()->GetTransceivers().size());

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

  EXPECT_EQ(2u, caller->pc()->GetTransceivers().size());
  EXPECT_EQ(2u, callee->pc()->GetTransceivers().size());
}

// Tests for MSID properties.

// Test that adding a track with AddTrack results in an offer that signals the
// track's ID.
TEST_F(PeerConnectionJsepTest, AddingTrackWithAddTrackSpecifiesTrackId) {
  const std::string kTrackId = "audio_track";

  auto caller = CreatePeerConnection();
  caller->AddAudioTrack(kTrackId);

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  auto streams = contents[0].media_description()->streams();
  ASSERT_EQ(1u, streams.size());
  EXPECT_EQ(kTrackId, streams[0].id);
}

// Test that adding a track by calling AddTransceiver then SetTrack results in
// an offer that does not signal the track's ID and signals a random ID.
TEST_F(PeerConnectionJsepTest,
       AddingTrackWithAddTransceiverSpecifiesRandomTrackId) {
  const std::string kTrackId = "audio_track";

  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  transceiver->sender()->SetTrack(caller->CreateAudioTrack(kTrackId).get());

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(1u, contents.size());
  auto streams = contents[0].media_description()->streams();
  ASSERT_EQ(1u, streams.size());
  EXPECT_NE(kTrackId, streams[0].id);
}

// Test that if the transceiver is recvonly or inactive, then no MSID
// information is included in the offer.
TEST_F(PeerConnectionJsepTest, NoMsidInOfferIfTransceiverDirectionHasNoSend) {
  auto caller = CreatePeerConnection();

  RtpTransceiverInit init_recvonly;
  init_recvonly.direction = RtpTransceiverDirection::kRecvOnly;
  ASSERT_TRUE(caller->AddTransceiver(MediaType::AUDIO, init_recvonly));

  RtpTransceiverInit init_inactive;
  init_inactive.direction = RtpTransceiverDirection::kInactive;
  ASSERT_TRUE(caller->AddTransceiver(MediaType::VIDEO, init_inactive));

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  auto contents = offer->description()->contents();
  ASSERT_EQ(2u, contents.size());
  // MSID is specified in the first stream, so no streams means no MSID.
  EXPECT_EQ(0u, contents[0].media_description()->streams().size());
  EXPECT_EQ(0u, contents[1].media_description()->streams().size());
}

// Test that if an answer negotiates transceiver directions of recvonly or
// inactive, then no MSID information is included in the answer.
TEST_F(PeerConnectionJsepTest, NoMsidInAnswerIfNoRespondingTracks) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  // recvonly transceiver will get negotiated to inactive since the callee has
  // no tracks to send in response.
  RtpTransceiverInit init_recvonly;
  init_recvonly.direction = RtpTransceiverDirection::kRecvOnly;
  caller->AddTransceiver(MediaType::AUDIO, init_recvonly);

  // sendrecv transceiver will get negotiated to recvonly since the callee has
  // no tracks to send in response.
  RtpTransceiverInit init_sendrecv;
  init_sendrecv.direction = RtpTransceiverDirection::kSendRecv;
  caller->AddTransceiver(MediaType::VIDEO, init_sendrecv);

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

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  auto contents = answer->description()->contents();
  ASSERT_EQ(2u, contents.size());
  // MSID is specified in the first stream, so no streams means no MSID.
  EXPECT_EQ(0u, contents[0].media_description()->streams().size());
  EXPECT_EQ(0u, contents[1].media_description()->streams().size());
}

// Test that the MSID is included even if the transceiver direction has changed
// to inactive if the transceiver had previously sent media.
TEST_F(PeerConnectionJsepTest, IncludeMsidEvenIfDirectionHasChanged) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");

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

  caller->pc()->GetTransceivers()[0]->SetDirectionWithError(
      RtpTransceiverDirection::kInactive);

  // The transceiver direction on both sides will turn to inactive.
  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  auto* offer = callee->pc()->remote_description();
  auto offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  // MSID is specified in the first stream. If it is present, assume that MSID
  // is there.
  EXPECT_EQ(1u, offer_contents[0].media_description()->streams().size());

  auto* answer = caller->pc()->remote_description();
  auto answer_contents = answer->description()->contents();
  ASSERT_EQ(1u, answer_contents.size());
  EXPECT_EQ(1u, answer_contents[0].media_description()->streams().size());
}

// Test that stopping a RtpTransceiver will cause future offers to not include
// any MSID information for that section.
TEST_F(PeerConnectionJsepTest, RemoveMsidIfTransceiverStopped) {
  auto caller = CreatePeerConnection();
  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();

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

  transceiver->StopInternal();

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

  auto* offer = callee->pc()->remote_description();
  auto offer_contents = offer->description()->contents();
  ASSERT_EQ(1u, offer_contents.size());
  // MSID is specified in the first stream, so no streams means no MSID.
  EXPECT_EQ(0u, offer_contents[0].media_description()->streams().size());
}

// Test that the callee RtpReceiver created by a call to SetRemoteDescription
// has its ID set to the signaled track ID.
TEST_F(PeerConnectionJsepTest,
       RtpReceiverCreatedBySetRemoteDescriptionHasSignaledTrackId) {
  const std::string kTrackId = "audio_track";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddAudioTrack(kTrackId);

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

  ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
  auto receiver = callee->pc()->GetReceivers()[0];
  EXPECT_EQ(kTrackId, receiver->id());
}

// Test that if the callee RtpReceiver is reused by a call to
// SetRemoteDescription, its ID does not change.
TEST_F(PeerConnectionJsepTest,
       RtpReceiverCreatedBeforeSetRemoteDescriptionKeepsId) {
  const std::string kTrackId = "audio_track";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddAudioTrack(kTrackId);
  callee->AddAudioTrack("dummy_track");

  ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
  auto receiver = callee->pc()->GetReceivers()[0];
  std::string receiver_id = receiver->id();

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

  EXPECT_EQ(receiver_id, receiver->id());
}

// Test that setting a remote offer with one track that has no streams fires off
// the correct OnAddTrack event.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferWithOneTrackNoStreamFiresOnAddTrack) {
  const std::string kTrackLabel = "audio_track";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(caller->AddAudioTrack(kTrackLabel));

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

  const auto& track_events = callee->observer()->add_track_events_;
  ASSERT_EQ(1u, track_events.size());
  const auto& event = track_events[0];
  EXPECT_EQ(kTrackLabel, event.receiver->track()->id());
  EXPECT_EQ(0u, event.streams.size());
}

// Test that setting a remote offer with one track that has one stream fires off
// the correct OnAddTrack event.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferWithOneTrackOneStreamFiresOnAddTrack) {
  const std::string kTrackLabel = "audio_track";
  const std::string kStreamId = "audio_stream";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(caller->AddAudioTrack(kTrackLabel, {kStreamId}));

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

  const auto& track_events = callee->observer()->add_track_events_;
  ASSERT_EQ(1u, track_events.size());
  const auto& event = track_events[0];
  ASSERT_EQ(1u, event.streams.size());
  auto stream = event.streams[0];
  EXPECT_EQ(kStreamId, stream->id());
  EXPECT_THAT(track_events[0].snapshotted_stream_tracks.at(stream),
              ElementsAre(event.receiver->track()));
  EXPECT_EQ(event.receiver->streams(), track_events[0].streams);
}

// Test that setting a remote offer with two tracks that share the same stream
// fires off two OnAddTrack events, both with the same stream that has both
// tracks present at the time of firing. This is to ensure that track events are
// not fired until SetRemoteDescription has finished processing all the media
// sections.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferWithTwoTracksSameStreamFiresOnAddTrack) {
  const std::string kTrack1Label = "audio_track1";
  const std::string kTrack2Label = "audio_track2";
  const std::string kSharedStreamId = "stream";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(caller->AddAudioTrack(kTrack1Label, {kSharedStreamId}));
  ASSERT_TRUE(caller->AddAudioTrack(kTrack2Label, {kSharedStreamId}));

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

  const auto& track_events = callee->observer()->add_track_events_;
  ASSERT_EQ(2u, track_events.size());
  const auto& event1 = track_events[0];
  const auto& event2 = track_events[1];
  ASSERT_EQ(1u, event1.streams.size());
  auto stream = event1.streams[0];
  ASSERT_THAT(event2.streams, ElementsAre(stream));
  auto track1 = event1.receiver->track();
  auto track2 = event2.receiver->track();
  EXPECT_THAT(event1.snapshotted_stream_tracks.at(stream),
              UnorderedElementsAre(track1, track2));
  EXPECT_THAT(event2.snapshotted_stream_tracks.at(stream),
              UnorderedElementsAre(track1, track2));
}

// Test that setting a remote offer with one track that has two streams fires
// off the correct OnAddTrack event.
TEST_F(PeerConnectionJsepTest,
       SetRemoteOfferWithOneTrackTwoStreamFiresOnAddTrack) {
  const std::string kTrackLabel = "audio_track";
  const std::string kStreamId1 = "audio_stream1";
  const std::string kStreamId2 = "audio_stream2";

  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  ASSERT_TRUE(caller->AddAudioTrack(kTrackLabel, {kStreamId1, kStreamId2}));

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

  const auto& track_events = callee->observer()->add_track_events_;
  ASSERT_EQ(1u, track_events.size());
  const auto& event = track_events[0];
  ASSERT_EQ(2u, event.streams.size());
  EXPECT_EQ(kStreamId1, event.streams[0]->id());
  EXPECT_EQ(kStreamId2, event.streams[1]->id());
}

// Test that if an RtpTransceiver with a current_direction set is stopped, then
// current_direction is changed to null.
TEST_F(PeerConnectionJsepTest, CurrentDirectionResetWhenRtpTransceiverStopped) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  auto transceiver = caller->AddTransceiver(MediaType::AUDIO);

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

  ASSERT_TRUE(transceiver->current_direction());
  transceiver->StopInternal();
  EXPECT_EQ(transceiver->current_direction(),
            RtpTransceiverDirection::kStopped);
}

// Test that you can't set an answer on a PeerConnection before setting the
// offer.
TEST_F(PeerConnectionJsepTest, AnswerBeforeOfferFails) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddAudioTrack("audio");

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

  RTCError error;
  ASSERT_FALSE(caller->SetRemoteDescription(callee->CreateAnswer(), &error));
  EXPECT_EQ(RTCErrorType::INVALID_STATE, error.type());
}

// Test that a Unified Plan PeerConnection fails to set a Plan B offer if it has
// two video tracks.
TEST_F(PeerConnectionJsepTest, TwoVideoPlanBToUnifiedPlanFails) {
  RTCConfiguration config_planb;
  config_planb.sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
  auto caller = CreatePeerConnection(config_planb);
  auto callee = CreatePeerConnection();
  caller->AddVideoTrack("video1");
  caller->AddVideoTrack("video2");

  RTCError error;
  ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer(), &error));
  EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
}

// Test that a Unified Plan PeerConnection fails to set a Plan B answer if it
// has two video tracks.
TEST_F(PeerConnectionJsepTest, OneVideoUnifiedPlanToTwoVideoPlanBFails) {
  auto caller = CreatePeerConnection();
  RTCConfiguration config_planb;
  config_planb.sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
  auto callee = CreatePeerConnection(config_planb);
  caller->AddVideoTrack("video");
  callee->AddVideoTrack("video1");
  callee->AddVideoTrack("video2");

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

  RTCError error;
  ASSERT_FALSE(caller->SetRemoteDescription(caller->CreateAnswer(), &error));
  EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
}

// Removes the RTP header extension associated with the given URI from the media
// description.
static void RemoveRtpHeaderExtensionByUri(
    MediaContentDescription* media_description,
    absl::string_view uri) {
  std::vector<RtpExtension> header_extensions =
      media_description->rtp_header_extensions();
  std::erase_if(header_extensions, [uri](const RtpExtension& extension) {
    return extension.uri == uri;
  });
  media_description->set_rtp_header_extensions(header_extensions);
}

// Transforms a session description to emulate a legacy endpoint which does not
// support a=mid, BUNDLE, and the MID header extension.
static void ClearMids(SessionDescriptionInterface* sdesc) {
  SessionDescription* desc = sdesc->description();
  desc->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  ContentInfo* audio_content = GetFirstAudioContent(desc);
  if (audio_content) {
    desc->GetTransportInfoByName(audio_content->mid())->content_name = "";
    audio_content->set_mid("");
    RemoveRtpHeaderExtensionByUri(audio_content->media_description(),
                                  RtpExtension::kMidUri);
  }
  ContentInfo* video_content = GetFirstVideoContent(desc);
  if (video_content) {
    desc->GetTransportInfoByName(video_content->mid())->content_name = "";
    video_content->set_mid("");
    RemoveRtpHeaderExtensionByUri(video_content->media_description(),
                                  RtpExtension::kMidUri);
  }
}

// Test that negotiation works with legacy endpoints which do not support a=mid.
TEST_F(PeerConnectionJsepTest, LegacyNoMidAudioOnlyOffer) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ClearMids(offer.get());

  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  EXPECT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
}
TEST_F(PeerConnectionJsepTest, LegacyNoMidAudioVideoOffer) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  caller->AddVideoTrack("video");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");
  callee->AddVideoTrack("video");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ClearMids(offer.get());

  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  EXPECT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
}
TEST_F(PeerConnectionJsepTest, LegacyNoMidAudioOnlyAnswer) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");

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

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  ClearMids(answer.get());

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(answer)));
}
TEST_F(PeerConnectionJsepTest, LegacyNoMidAudioVideoAnswer) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  caller->AddVideoTrack("video");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");
  callee->AddVideoTrack("video");

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

  std::unique_ptr<SessionDescriptionInterface> answer = callee->CreateAnswer();
  ClearMids(answer.get());

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

// Test that negotiation works with legacy endpoints which do not support a=mid
// when setting two remote descriptions without setting a local description in
// between.
TEST_F(PeerConnectionJsepTest, LegacyNoMidTwoRemoteOffers) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("audio");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ClearMids(offer.get());

  ASSERT_TRUE(callee->SetRemoteDescription(offer->Clone()));
  ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  EXPECT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
}

// Test that SetLocalDescription fails if a=mid lines are missing.
TEST_F(PeerConnectionJsepTest, SetLocalDescriptionFailsMissingMid) {
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("audio");

  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  ClearMids(offer.get());

  std::string error;
  ASSERT_FALSE(caller->SetLocalDescription(std::move(offer), &error));
  EXPECT_EQ(
      "Failed to set local offer sdp: A media section is missing a MID "
      "attribute.",
      error);
}

TEST_F(PeerConnectionJsepTest, RollbackSupportedInUnifiedPlan) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->SetRemoteDescription(callee->CreateOffer()));
}

TEST_F(PeerConnectionJsepTest, RollbackNotSupportedInPlanB) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_FALSE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_FALSE(caller->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_FALSE(caller->SetRemoteDescription(callee->CreateOffer()));
}

TEST_F(PeerConnectionJsepTest, RollbackFailsInStableState) {
  auto caller = CreatePeerConnection();
  EXPECT_FALSE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_FALSE(caller->SetRemoteDescription(caller->CreateRollback()));
}

TEST_F(PeerConnectionJsepTest, RollbackToStableStateAndClearLocalOffer) {
  auto caller = CreatePeerConnection();
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_EQ(caller->signaling_state(), PeerConnectionInterface::kStable);
  EXPECT_EQ(caller->pc()->pending_local_description(), nullptr);

  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(caller->signaling_state(), PeerConnectionInterface::kStable);
  EXPECT_EQ(caller->pc()->pending_local_description(), nullptr);
}

TEST_F(PeerConnectionJsepTest, RollbackToStableStateAndClearRemoteOffer) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->signaling_state(), PeerConnectionInterface::kStable);
  EXPECT_EQ(callee->pc()->pending_remote_description(), nullptr);

  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetLocalDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->signaling_state(), PeerConnectionInterface::kStable);
  EXPECT_EQ(callee->pc()->pending_remote_description(), nullptr);
}

TEST_F(PeerConnectionJsepTest, RollbackImplicitly) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->signaling_state(),
            PeerConnectionInterface::kHaveRemoteOffer);
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
  EXPECT_FALSE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_FALSE(callee->observer()->has_negotiation_needed_event());
}

TEST_F(PeerConnectionJsepTest, RollbackImplicitlyNegotatiationNotNeeded) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  caller->AddAudioTrack("a");
  callee->AddAudioTrack("b");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  callee->observer()->clear_legacy_renegotiation_needed();
  callee->observer()->clear_latest_negotiation_needed_event();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->signaling_state(),
            PeerConnectionInterface::kHaveRemoteOffer);
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
  // No negotiation needed as track got attached in the answer.
  EXPECT_FALSE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_FALSE(callee->observer()->has_negotiation_needed_event());
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 0u);
}

TEST_F(PeerConnectionJsepTest, RollbackImplicitlyAndNegotiationNeeded) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  callee->AddAudioTrack("a");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  callee->observer()->clear_legacy_renegotiation_needed();
  callee->observer()->clear_latest_negotiation_needed_event();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->signaling_state(),
            PeerConnectionInterface::kHaveRemoteOffer);
  EXPECT_FALSE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_FALSE(callee->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
  EXPECT_TRUE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 0u);
}

TEST_F(PeerConnectionJsepTest, AttemptToRollbackImplicitly) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_FALSE(callee->SetRemoteDescription(
      CreateSessionDescription(SdpType::kOffer, "invalid sdp")));
  EXPECT_EQ(callee->signaling_state(),
            PeerConnectionInterface::kHaveLocalOffer);
}

TEST_F(PeerConnectionJsepTest, RollbackRemovesTransceiver) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  ASSERT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  auto transceiver = callee->pc()->GetTransceivers()[0];
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 0u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
  // The removed transceiver should be stopped and its receiver track should be
  // ended.
  EXPECT_TRUE(transceiver->stopping());
  EXPECT_TRUE(transceiver->stopping());
  EXPECT_EQ(transceiver->receiver()->track()->state(),
            MediaStreamTrackInterface::kEnded);
}

TEST_F(PeerConnectionJsepTest, RollbackKeepsTransceiverAndClearsMid) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  callee->AddAudioTrack("a");
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  // Transceiver can't be removed as track was added to it.
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  // Mid got cleared to make it reusable.
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  // Transceiver should be counted as addTrack-created after rollback.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
  // Because the transceiver is reusable, it must not be stopped and its
  // receiver track must still be live.
  auto transceiver = callee->pc()->GetTransceivers()[0];
  EXPECT_FALSE(transceiver->stopping());
  EXPECT_FALSE(transceiver->stopping());
  EXPECT_EQ(transceiver->receiver()->track()->state(),
            MediaStreamTrackInterface::kLive);
}

TEST_F(PeerConnectionJsepTest,
       RollbackKeepsTransceiverAfterAddTrackEvenWhenTrackIsNulled) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  callee->AddAudioTrack("a");
  callee->pc()->GetTransceivers()[0]->sender()->SetTrack(nullptr);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->sender()->track(), nullptr);
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  // Transceiver can't be removed as track was added to it.
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  // Mid got cleared to make it reusable.
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  // Transceiver should be counted as addTrack-created after rollback.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
}

TEST_F(PeerConnectionJsepTest, RollbackRestoresMid) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  std::unique_ptr<SessionDescriptionInterface> offer = callee->CreateOffer();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_NE(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  EXPECT_TRUE(callee->SetLocalDescription(std::move(offer)));
}

TEST_F(PeerConnectionJsepTest, RollbackRestoresInitSendEncodings) {
  auto caller = CreatePeerConnection();
  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendRecv;
  RtpEncodingParameters encoding;
  encoding.rid = "hi";
  init.send_encodings.push_back(encoding);
  encoding.rid = "mid";
  init.send_encodings.push_back(encoding);
  encoding.rid = "lo";
  init.send_encodings.push_back(encoding);
  caller->AddTransceiver(MediaType::VIDEO, init);
  auto encodings =
      caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings();
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
  EXPECT_NE(caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings(),
            encodings);
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_EQ(caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings(),
            encodings);
}

TEST_F(PeerConnectionJsepTest, RollbackDoesNotAffectSendEncodings) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding;
  encoding.rid = "hi";
  init.send_encodings.push_back(encoding);
  encoding.rid = "mid";
  init.send_encodings.push_back(encoding);
  encoding.rid = "lo";
  init.send_encodings.push_back(encoding);
  caller->AddTransceiver(MediaType::VIDEO, init);
  callee->AddTransceiver(MediaType::VIDEO);
  callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
  caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal());
  auto params = caller->pc()->GetTransceivers()[0]->sender()->GetParameters();
  EXPECT_TRUE(params.encodings[0].active);
  params.encodings[0].active = false;
  caller->pc()->GetTransceivers()[0]->sender()->SetParameters(params);
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  std::string offer_string;
  EXPECT_TRUE(offer.get()->ToString(&offer_string));
  std::string simulcast_line =
      offer_string.substr(offer_string.find("a=simulcast"));
  EXPECT_FALSE(simulcast_line.empty());
  EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));
  EXPECT_FALSE(caller->pc()
                   ->GetTransceivers()[0]
                   ->sender()
                   ->GetParameters()
                   .encodings[0]
                   .active);
  offer = caller->CreateOffer();
  EXPECT_TRUE(offer.get()->ToString(&offer_string));
  EXPECT_EQ(offer_string.substr(offer_string.find("a=simulcast")),
            simulcast_line);
}

TEST_F(PeerConnectionJsepTest, RollbackRestoresMidAndRemovesTransceiver) {
  auto callee = CreatePeerConnection();
  callee->AddVideoTrack("a");
  std::unique_ptr<SessionDescriptionInterface> offer = callee->CreateOffer();
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("b");
  caller->AddVideoTrack("c");
  auto mid = callee->pc()->GetTransceivers()[0]->mid();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), mid);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->media_type(), MediaType::VIDEO);
  EXPECT_TRUE(callee->SetLocalDescription(std::move(offer)));
  EXPECT_EQ(callee->observer()->remove_track_events_.size(),
            callee->observer()->add_track_events_.size());
}

TEST_F(PeerConnectionJsepTest, RollbackHasNoEffectOnStableTransceivers) {
  auto callee = CreatePeerConnection();
  callee->AddVideoTrack("a");
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("b");
  caller->AddVideoTrack("c");
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
  // In stable don't add or remove anything.
  callee->observer()->clear_legacy_renegotiation_needed();
  callee->observer()->clear_latest_negotiation_needed_event();
  size_t transceiver_count = callee->pc()->GetTransceivers().size();
  auto mid_0 = callee->pc()->GetTransceivers()[0]->mid();
  auto mid_1 = callee->pc()->GetTransceivers()[1]->mid();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), transceiver_count);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), mid_0);
  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(), mid_1);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 0u);
  EXPECT_FALSE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_FALSE(callee->observer()->has_negotiation_needed_event());
}

TEST_F(PeerConnectionJsepTest, ImplicitlyRollbackTransceiversWithSameMids) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  caller->AddTransceiver(MediaType::VIDEO);
  auto callee = CreatePeerConnection(config);
  callee->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  auto initial_mid = callee->pc()->GetTransceivers()[0]->mid();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(),
            caller->pc()->GetTransceivers()[0]->mid());
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());  // Go to stable.
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_NE(callee->pc()->GetTransceivers()[0]->mid(), initial_mid);
}

TEST_F(PeerConnectionJsepTest, RollbackToNegotiatedStableState) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
  auto caller = CreatePeerConnection(config);
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection(config);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
  caller->AddVideoTrack("a");
  callee->AddVideoTrack("b");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
  auto audio_transport =
      callee->pc()->GetTransceivers()[0]->sender()->dtls_transport();
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            callee->pc()->GetTransceivers()[1]->sender()->dtls_transport());
  EXPECT_NE(callee->pc()->GetTransceivers()[1]->sender()->dtls_transport(),
            nullptr);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            audio_transport);  // Audio must remain working after rollback.
  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->sender()->dtls_transport(),
            nullptr);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            audio_transport);  // Audio transport is still the same.
}

TEST_F(PeerConnectionJsepTest, RollbackHasToDestroyTransport) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
  auto pc = CreatePeerConnection(config);
  pc->AddAudioTrack("a");
  pc->AddVideoTrack("b");
  EXPECT_TRUE(pc->CreateOfferAndSetAsLocal());
  std::unique_ptr<SessionDescriptionInterface> offer = pc->CreateOffer();
  EXPECT_EQ(pc->pc()->GetTransceivers().size(), 2u);
  auto audio_transport =
      pc->pc()->GetTransceivers()[0]->sender()->dtls_transport();
  EXPECT_EQ(pc->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            pc->pc()->GetTransceivers()[1]->sender()->dtls_transport());
  EXPECT_NE(pc->pc()->GetTransceivers()[1]->sender()->dtls_transport(),
            nullptr);
  EXPECT_TRUE(pc->SetRemoteDescription(pc->CreateRollback()));
  EXPECT_TRUE(pc->SetLocalDescription(std::move(offer)));
  EXPECT_NE(pc->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            nullptr);
  EXPECT_NE(pc->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            audio_transport);
}

TEST_F(PeerConnectionJsepTest, RollbackLocalDirectionChange) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
  callee->AddAudioTrack("a");
  callee->pc()->GetTransceivers()[0]->SetDirectionWithError(
      RtpTransceiverDirection::kSendOnly);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  auto audio_transport =
      callee->pc()->GetTransceivers()[0]->receiver()->dtls_transport();
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->direction(),
            RtpTransceiverDirection::kSendOnly);
  // One way audio must remain working after rollback as local direction change
  // comes in effect after completing full negotiation round.
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->receiver()->dtls_transport(),
            audio_transport);
}

TEST_F(PeerConnectionJsepTest, RollbackRemoteDirectionChange) {
  auto caller = CreatePeerConnection();
  auto caller_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
  // In stable make remote audio receive only.
  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  // The direction attribute is not modified by the offer.
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->direction(),
            RtpTransceiverDirection::kSendRecv);
  auto audio_transport =
      callee->pc()->GetTransceivers()[0]->sender()->dtls_transport();
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->direction(),
            RtpTransceiverDirection::kSendRecv);
  // One way audio must remain working after rollback.
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->sender()->dtls_transport(),
            audio_transport);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
}

TEST_F(PeerConnectionJsepTest,
       RollbackRestoresFiredDirectionAndOnTrackCanFireAgain) {
  auto caller = CreatePeerConnection();
  auto caller_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  callee->AddAudioTrack("a");
  ASSERT_EQ(callee->pc()->GetTransceivers().size(), 1u);
  auto callee_transceiver = callee->pc()->GetTransceivers()[0];
  EXPECT_FALSE(callee_transceiver->fired_direction().has_value());
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(callee_transceiver->fired_direction().has_value());
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
  // The existing transceiver becomes associated. Because it already exists,
  // rolling it back does not remove the transceiver, so if ontrack fires again
  // later it will be because the transceiver's internal states were restored
  // rather than due to the creation of a new transceiver.
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);

  // Rollback: the transceiver is no longer receiving.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_FALSE(callee_transceiver->fired_direction().has_value());
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);

  // Set the remote offer again: ontrack should fire on the same transceiver.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(callee_transceiver->fired_direction().has_value());
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 2u);
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
}

TEST_F(PeerConnectionJsepTest,
       RollbackFromInactiveToReceivingMakesOnTrackFire) {
  auto caller = CreatePeerConnection();
  auto caller_transceiver = caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  // Perform full O/A so that transceiver is associated. Ontrack fires.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 0u);
  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  // Start negotiating to make the transceiver inactive. Onremovetrack fires.
  caller_transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);

  // Rollback the inactivation. Ontrack should fire again.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
  EXPECT_EQ(callee->observer()->add_track_events_.size(), 2u);
  EXPECT_EQ(callee->observer()->remove_track_events_.size(), 1u);
}

TEST_F(PeerConnectionJsepTest, RollbackAfterMultipleSLD) {
  auto callee = CreatePeerConnection();
  callee->AddTransceiver(MediaType::AUDIO);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  callee->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  callee->observer()->clear_legacy_renegotiation_needed();
  callee->observer()->clear_latest_negotiation_needed_event();
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  EXPECT_TRUE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
  EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(), std::nullopt);
}

TEST_F(PeerConnectionJsepTest, NoRollbackNeeded) {
  auto caller = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  auto callee = CreatePeerConnection();
  callee->AddTransceiver(MediaType::AUDIO);
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
}

TEST_F(PeerConnectionJsepTest, RollbackMultipleStreamChanges) {
  auto callee = CreatePeerConnection();
  auto caller = CreatePeerConnection();
  caller->AddAudioTrack("a_1", {"id_1"});
  caller->AddVideoTrack("v_0", {"id_0"});  // Provide an extra stream id.
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
  caller->pc()->GetTransceivers()[0]->sender()->SetStreams({"id_2"});
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  caller->pc()->GetTransceivers()[0]->sender()->SetStreams({"id_3"});
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->receiver()->stream_ids()[0],
            "id_3");
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->receiver()->stream_ids().size(),
            1u);
  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->receiver()->stream_ids()[0],
            "id_1");
}

TEST_F(PeerConnectionJsepTest, DataChannelImplicitRollback) {
  RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  config.enable_implicit_rollback = true;
  auto caller = CreatePeerConnection(config);
  caller->AddTransceiver(MediaType::VIDEO);
  auto callee = CreatePeerConnection(config);
  callee->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());
  EXPECT_TRUE(callee->observer()->legacy_renegotiation_needed());
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest, RollbackRemoteDataChannelThenAddTransceiver) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  callee->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest,
       RollbackRemoteDataChannelThenAddTransceiverAndDataChannel) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  callee->AddTransceiver(MediaType::VIDEO);
  callee->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest, RollbackFollowedByAddTrack) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendRecv;
  RtpEncodingParameters encoding;
  encoding.rid = "hi";
  init.send_encodings.push_back(encoding);
  caller->AddTransceiver(MediaType::VIDEO, init);

  auto video_track = caller->CreateVideoTrack("v");
  caller->pc()->GetTransceivers()[0]->sender()->SetTrack(video_track.get());

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

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

  // Create and apply local offer.
  ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());

  // Rollback.
  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));

  // Add track to the video transceiver.
  auto video_track2 = caller->CreateVideoTrack("v2");
  caller->pc()->GetTransceivers()[0]->sender()->SetTrack(video_track2.get());

  // Verify no crash and operation succeeds.
  EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest, RollbackAfterSetParametersDoesNotStopAudio) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddAudioTrack("a");
  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  ASSERT_EQ(caller->pc()->GetTransceivers().size(), 1u);
  auto transceiver = caller->pc()->GetTransceivers()[0];

  auto params = transceiver->sender()->GetParameters();
  ASSERT_FALSE(params.encodings.empty());
  EXPECT_NE(params.encodings[0].ssrc, std::nullopt);

  // Verify init_send_encodings are empty BEFORE SetParameters.
  EXPECT_TRUE(transceiver->sender()->init_send_encodings().empty());
  EXPECT_EQ(transceiver->sender()->SetParameters(params).type(),
            RTCErrorType::NONE);

  // Verify that init_send_encodings are empty because no initial encodings were
  // provided during transceiver creation.
  EXPECT_TRUE(transceiver->sender()->init_send_encodings().empty());

  ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());

  ASSERT_TRUE(caller->SetLocalDescription(caller->CreateRollback()));

  EXPECT_FALSE(transceiver->stopping());
  EXPECT_EQ(transceiver->receiver()->track()->state(),
            MediaStreamTrackInterface::kLive);
}

TEST_F(PeerConnectionJsepTest, RollbackRemoteDataChannelThenAddDataChannel) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  callee->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest, RollbackRemoteTransceiverThenAddDataChannel) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  callee->CreateDataChannel("dummy");
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest,
       RollbackRemoteTransceiverThenAddDataChannelAndTransceiver) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(callee->CreateRollback()));
  callee->CreateDataChannel("dummy");
  callee->AddTransceiver(MediaType::VIDEO);
  EXPECT_TRUE(callee->CreateOfferAndSetAsLocal());
}

TEST_F(PeerConnectionJsepTest, BundleOnlySectionDoesNotNeedRtcpMux) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  caller->AddTransceiver(MediaType::AUDIO);
  caller->AddTransceiver(MediaType::VIDEO);
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  // Remove rtcp-mux and set bundle-only on the second content.
  offer->description()->contents()[1].media_description()->set_rtcp_mux(false);
  offer->description()->contents()[1].bundle_only = true;

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

TEST_F(PeerConnectionJsepTest, RtcpMuxNotNegotiated) {
  RTCConfiguration config;
  // Non-standard as `require` is the only standardized value but we can not
  // remove support for non-mux.
  config.rtcp_mux_policy =
      PeerConnection::RtcpMuxPolicy::kRtcpMuxPolicyNegotiate;
  auto caller = CreatePeerConnection(config);
  auto callee = CreatePeerConnection(config);
  caller->AddTransceiver(MediaType::AUDIO);
  std::unique_ptr<SessionDescriptionInterface> offer =
      caller->CreateOfferAndSetAsLocal();
  ASSERT_THAT(offer, NotNull());
  ASSERT_THAT(offer->description()->contents(), SizeIs(1));
  // Remove BUNDLE and rtcp-mux.
  offer->description()->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  offer->description()->contents()[0].media_description()->set_rtcp_mux(false);

  EXPECT_TRUE(callee->SetRemoteDescription(std::move(offer)));
  std::unique_ptr<SessionDescriptionInterface> answer =
      callee->CreateAnswerAndSetAsLocal();
  EXPECT_THAT(answer, NotNull());
  EXPECT_TRUE(caller->SetRemoteDescription(std::move(answer)));

  auto report = caller->GetStats();
  ASSERT_THAT(report, NotNull());

  std::vector<const RTCTransportStats*> transports =
      report->GetStatsOfType<RTCTransportStats>();
  EXPECT_THAT(transports, SizeIs(2));
}

// This test is a regression test for crbug.com/410960672
TEST_F(PeerConnectionJsepTest, OfferRollbackRemoveReoffer) {
  auto caller = CreatePeerConnection();
  // Add first video track.
  auto sender = caller->AddVideoTrack("foo");
  caller->SetLocalDescription(caller->CreateOffer());
  caller->SetRemoteDescription(caller->CreateRollback());
  RTCError error = caller->pc()->RemoveTrackOrError(sender);
  EXPECT_THAT(error, IsRtcOk());
  std::unique_ptr<SessionDescriptionInterface> offer = caller->CreateOffer();
  caller->SetLocalDescription(std::move(offer));
}

}  // namespace webrtc
