/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// This file contains tests that check the PeerConnection's signaling state
// machine, as well as tests that check basic, media-agnostic aspects of SDP.

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

#include "api/audio/audio_device.h"
#include "api/audio/audio_mixer.h"
#include "api/audio/audio_processing.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/create_peerconnection_factory.h"
#include "api/dtls_transport_interface.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_receiver_interface.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/set_local_description_observer_interface.h"
#include "api/set_remote_description_observer_interface.h"
#include "api/video_codecs/video_decoder_factory_template.h"
#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
#include "api/video_codecs/video_encoder_factory_template.h"
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
#include "media/base/codec.h"
#include "p2p/base/port_allocator.h"
#include "pc/peer_connection.h"
#include "pc/peer_connection_proxy.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/sdp_utils.h"
#include "pc/session_description.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/checks.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/thread.h"
#include "test/gmock.h"
#include "test/gtest.h"
#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif
#include "pc/test/fake_audio_capture_module.h"
#include "pc/test/fake_rtc_certificate_generator.h"
#include "rtc_base/gunit.h"
#include "rtc_base/virtual_socket_server.h"

namespace webrtc {

using SignalingState = PeerConnectionInterface::SignalingState;
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
using ::testing::Bool;
using ::testing::Combine;
using ::testing::StartsWith;
using ::testing::Values;

namespace {
const int64_t kWaitTimeout = 10000;
}  // namespace

class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
 public:
  using PeerConnectionWrapper::PeerConnectionWrapper;

  bool initial_offerer() {
    return GetInternalPeerConnection()->initial_offerer();
  }

  PeerConnection* GetInternalPeerConnection() {
    auto* pci =
        static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
            pc());
    return static_cast<PeerConnection*>(pci->internal());
  }
};

class ExecuteFunctionOnCreateSessionDescriptionObserver
    : public CreateSessionDescriptionObserver {
 public:
  ExecuteFunctionOnCreateSessionDescriptionObserver(
      std::function<void(SessionDescriptionInterface*)> function)
      : function_(std::move(function)) {}
  ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
    RTC_DCHECK(was_called_);
  }

  bool was_called() const { return was_called_; }

  void OnSuccess(SessionDescriptionInterface* desc) override {
    RTC_DCHECK(!was_called_);
    was_called_ = true;
    function_(desc);
  }

  void OnFailure(RTCError error) override { RTC_DCHECK_NOTREACHED(); }

 private:
  bool was_called_ = false;
  std::function<void(SessionDescriptionInterface*)> function_;
};

class PeerConnectionSignalingBaseTest : public ::testing::Test {
 protected:
  typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;

  explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
      : vss_(new rtc::VirtualSocketServer()),
        main_(vss_.get()),
        sdp_semantics_(sdp_semantics) {
#ifdef WEBRTC_ANDROID
    InitializeAndroidObjects();
#endif
    pc_factory_ = CreatePeerConnectionFactory(
        rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
        rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
        CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
        std::make_unique<VideoEncoderFactoryTemplate<
            LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter,
            OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>(),
        std::make_unique<VideoDecoderFactoryTemplate<
            LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter,
            OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(),
        nullptr /* audio_mixer */, nullptr /* audio_processing */);
  }

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

  WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
    auto observer = std::make_unique<MockPeerConnectionObserver>();
    RTCConfiguration modified_config = config;
    modified_config.sdp_semantics = sdp_semantics_;
    auto result = pc_factory_->CreatePeerConnectionOrError(
        modified_config, PeerConnectionDependencies(observer.get()));
    if (!result.ok()) {
      return nullptr;
    }

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

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

  int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
    std::set<DtlsTransportInterface*> transports;
    auto transceivers = pc_wrapper->pc()->GetTransceivers();

    for (auto& transceiver : transceivers) {
      if (transceiver->sender()->dtls_transport()) {
        EXPECT_TRUE(transceiver->receiver()->dtls_transport());
        EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
                  transceiver->receiver()->dtls_transport().get());
        transports.insert(transceiver->sender()->dtls_transport().get());
      } else {
        // If one transceiver is missing, they all should be.
        EXPECT_EQ(0UL, transports.size());
      }
    }
    return transports.size();
  }

  bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
    return NumberOfDtlsTransports(pc_wrapper) > 0;
  }

  std::unique_ptr<rtc::VirtualSocketServer> vss_;
  rtc::AutoSocketServerThread main_;
  rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
  const SdpSemantics sdp_semantics_;
};

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

TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
  auto caller = CreatePeerConnection();

  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
}

TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
}

TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
  auto caller = CreatePeerConnection();
  std::string error;
  ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
  EXPECT_EQ("SessionDescription is NULL.", error);
}

TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
  auto caller = CreatePeerConnection();
  std::string error;
  ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
  EXPECT_EQ("SessionDescription is NULL.", error);
}

// The following parameterized test verifies that calls to various signaling
// methods on PeerConnection will succeed/fail depending on what is the
// PeerConnection's signaling state. Note that the test tries many different
// forms of SignalingState::kClosed by arriving at a valid state then calling
// `Close()`. This is intended to catch cases where the PeerConnection signaling
// method ignores the closed flag but may work/not work because of the single
// state the PeerConnection was created in before it was closed.

class PeerConnectionSignalingStateTest
    : public PeerConnectionSignalingBaseTest,
      public ::testing::WithParamInterface<
          std::tuple<SdpSemantics, SignalingState, bool>> {
 protected:
  PeerConnectionSignalingStateTest()
      : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
        state_under_test_(std::make_tuple(std::get<1>(GetParam()),
                                          std::get<2>(GetParam()))) {}

  RTCConfiguration GetConfig() {
    RTCConfiguration config;
    config.certificates.push_back(
        FakeRTCCertificateGenerator::GenerateCertificate());
    return config;
  }

  WrapperPtr CreatePeerConnectionUnderTest() {
    return CreatePeerConnectionInState(state_under_test_);
  }

  WrapperPtr CreatePeerConnectionInState(SignalingState state) {
    return CreatePeerConnectionInState(std::make_tuple(state, false));
  }

  WrapperPtr CreatePeerConnectionInState(
      std::tuple<SignalingState, bool> state_tuple) {
    SignalingState state = std::get<0>(state_tuple);
    bool closed = std::get<1>(state_tuple);

    auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
    switch (state) {
      case SignalingState::kStable: {
        break;
      }
      case SignalingState::kHaveLocalOffer: {
        wrapper->SetLocalDescription(wrapper->CreateOffer());
        break;
      }
      case SignalingState::kHaveLocalPrAnswer: {
        auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
        wrapper->SetRemoteDescription(caller->CreateOffer());
        auto answer = wrapper->CreateAnswer();
        wrapper->SetLocalDescription(
            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
        break;
      }
      case SignalingState::kHaveRemoteOffer: {
        auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
        wrapper->SetRemoteDescription(caller->CreateOffer());
        break;
      }
      case SignalingState::kHaveRemotePrAnswer: {
        auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
        callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
        auto answer = callee->CreateAnswer();
        wrapper->SetRemoteDescription(
            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
        break;
      }
      case SignalingState::kClosed: {
        RTC_DCHECK_NOTREACHED()
            << "Set the second member of the tuple to true to "
               "achieve a closed state from an existing, valid "
               "state.";
      }
    }

    RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());

    if (closed) {
      wrapper->pc()->Close();
      RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
    }

    return wrapper;
  }

  std::tuple<SignalingState, bool> state_under_test_;
};

TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() != SignalingState::kClosed) {
    EXPECT_TRUE(wrapper->CreateOffer());
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
    EXPECT_EQ(error, "CreateOffer called when PeerConnection is closed.");
  }
}

TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->CreateAnswer());
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
    EXPECT_EQ(error,
              "PeerConnection cannot create an answer in a state other than "
              "have-remote-offer or have-local-pranswer.");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kStable ||
      wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
    // Need to call CreateOffer on the PeerConnection under test, otherwise when
    // setting the local offer it will want to verify the DTLS fingerprint
    // against the locally generated certificate, but without a call to
    // CreateOffer the certificate will never be generated.
    EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
  } else {
    auto wrapper_for_offer =
        CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
    auto offer =
        CloneSessionDescription(wrapper_for_offer->pc()->local_description());

    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
    EXPECT_THAT(
        error,
        StartsWith("Failed to set local offer sdp: Called in wrong state:"));
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
  auto wrapper_for_pranswer =
      CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
  auto pranswer =
      CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
    EXPECT_THAT(
        error,
        StartsWith("Failed to set local pranswer sdp: Called in wrong state:"));
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
  auto wrapper_for_answer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto answer = wrapper_for_answer->CreateAnswer();

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
    EXPECT_THAT(
        error,
        StartsWith("Failed to set local answer sdp: Called in wrong state:"));
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
  auto wrapper_for_offer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto offer =
      CloneSessionDescription(wrapper_for_offer->pc()->remote_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kStable ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
    EXPECT_THAT(
        error,
        StartsWith("Failed to set remote offer sdp: Called in wrong state:"));
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
  auto wrapper_for_pranswer =
      CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
  auto pranswer =
      CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
      wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
    EXPECT_THAT(
        error,
        StartsWith(
            "Failed to set remote pranswer sdp: Called in wrong state:"));
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
  auto wrapper_for_answer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto answer = wrapper_for_answer->CreateAnswer();

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
      wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
    EXPECT_THAT(
        error,
        StartsWith("Failed to set remote answer sdp: Called in wrong state:"));
  }
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
                         PeerConnectionSignalingStateTest,
                         Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
                                        SdpSemantics::kUnifiedPlan),
                                 Values(SignalingState::kStable,
                                        SignalingState::kHaveLocalOffer,
                                        SignalingState::kHaveLocalPrAnswer,
                                        SignalingState::kHaveRemoteOffer,
                                        SignalingState::kHaveRemotePrAnswer),
                                 Bool()));

// Test that CreateAnswer fails if a round of offer/answer has been done and
// the PeerConnection is in the stable state.
TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

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

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
  EXPECT_FALSE(caller->CreateAnswer());

  ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
  EXPECT_FALSE(callee->CreateAnswer());
}

// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
// stays the same but the version must be incremented if a later, different
// session description is generated. These two tests verify that is the case for
// both offers and answers.
TEST_P(PeerConnectionSignalingTest,
       SessionVersionIncrementedInSubsequentDifferentOffer) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  auto original_offer = caller->CreateOfferAndSetAsLocal();
  const std::string original_id = original_offer->session_id();
  const std::string original_version = original_offer->session_version();

  ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
  ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));

  // Add track to get a different offer.
  caller->AddAudioTrack("a");

  auto later_offer = caller->CreateOffer();

  EXPECT_EQ(original_id, later_offer->session_id());
  EXPECT_LT(rtc::FromString<uint64_t>(original_version),
            rtc::FromString<uint64_t>(later_offer->session_version()));
}
TEST_P(PeerConnectionSignalingTest,
       SessionVersionIncrementedInSubsequentDifferentAnswer) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

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

  auto original_answer = callee->CreateAnswer();
  const std::string original_id = original_answer->session_id();
  const std::string original_version = original_answer->session_version();

  // Add track to get a different answer.
  callee->AddAudioTrack("a");

  auto later_answer = callee->CreateAnswer();

  EXPECT_EQ(original_id, later_answer->session_id());
  EXPECT_LT(rtc::FromString<uint64_t>(original_version),
            rtc::FromString<uint64_t>(later_answer->session_version()));
}

TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  EXPECT_FALSE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());

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

  EXPECT_TRUE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());

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

  EXPECT_TRUE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());
}

// Test creating a PeerConnection, request multiple offers, destroy the
// PeerConnection and make sure we get success/failure callbacks for all of the
// requests.
// Background: crbug.com/507307
TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
  auto caller = CreatePeerConnection();

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio =
      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;

  rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
  for (auto& observer : observers) {
    observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
    caller->pc()->CreateOffer(observer.get(), options);
  }

  // Destroy the PeerConnection.
  caller.reset(nullptr);

  for (auto& observer : observers) {
    // We expect to have received a notification now even if the PeerConnection
    // was terminated. The offer creation may or may not have succeeded, but we
    // must have received a notification.
    EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  }
}

// Similar to the above test, but by closing the PC first the CreateOffer() will
// fail "early", which triggers a codepath where the PeerConnection is
// reponsible for invoking the observer, instead of the normal codepath where
// the WebRtcSessionDescriptionFactory is responsible for it.
TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  caller->pc()->Close();
  caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
  caller.reset(nullptr);
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
}

TEST_P(PeerConnectionSignalingTest,
       ImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(observer);
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer.get());
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer);
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller->pc()->Close();
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(observer);
  caller->pc()->Close();
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       SetLocalDescriptionNewObserverIsInvokedImmediately) {
  auto caller = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(std::move(offer), observer);
  // The new observer is invoked immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_TRUE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
  auto caller = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get(), offer.release());
  // The old observer is not invoked immediately.
  EXPECT_FALSE(observer->called());
  // Process all currently pending messages by waiting for a posted task to run.
  bool checkpoint_reached = false;
  rtc::Thread::Current()->PostTask(
      [&checkpoint_reached] { checkpoint_reached = true; });
  EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
  // If resolving the observer was pending, it must now have been called.
  EXPECT_TRUE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  // This offer will cause receivers to be created.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // By not waiting for the observer's callback we can verify that the operation
  // executed immediately.
  callee->pc()->SetRemoteDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
  EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
}

TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  // This offer will cause receivers to be created.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
  auto offer_observer =
      rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
  // SetRemoteDescription() operation should be chained to be executed
  // asynchronously, when CreateOffer() completes.
  callee->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
  callee->pc()->SetRemoteDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
  // CreateOffer() is asynchronous; without message processing this operation
  // should not have completed.
  EXPECT_FALSE(offer_observer->called());
  // Due to chaining, the receivers should not have been created by the offer
  // yet.
  EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
  // EXPECT_TRUE_WAIT causes messages to be processed...
  EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
  // Now that the offer has been completed, SetRemoteDescription() will have
  // been executed next in the chain.
  EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCreatesOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());

  // The offer is created asynchronously; message processing is needed for it to
  // complete.
  EXPECT_FALSE(observer->called());
  EXPECT_FALSE(caller->pc()->pending_local_description());
  EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());

  // Wait for messages to be processed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(observer->result());
  EXPECT_TRUE(caller->pc()->pending_local_description());
  EXPECT_EQ(SdpType::kOffer,
            caller->pc()->pending_local_description()->GetType());
  EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCreatesAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  callee->SetRemoteDescription(caller->CreateOffer());
  EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());

  auto observer = MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetLocalDescription(observer.get());

  // The answer is created asynchronously; message processing is needed for it
  // to complete.
  EXPECT_FALSE(observer->called());
  EXPECT_FALSE(callee->pc()->current_local_description());

  // Wait for messages to be processed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(observer->result());
  EXPECT_TRUE(callee->pc()->current_local_description());
  EXPECT_EQ(SdpType::kAnswer,
            callee->pc()->current_local_description()->GetType());
  EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionFullExchange) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  // SetLocalDescription(), implicitly creating an offer.
  auto caller_set_local_description_observer =
      MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(
      caller_set_local_description_observer.get());
  EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
                   kWaitTimeout);
  ASSERT_TRUE(caller->pc()->pending_local_description());

  // SetRemoteDescription(offer)
  auto callee_set_remote_description_observer =
      MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetRemoteDescription(
      callee_set_remote_description_observer.get(),
      CloneSessionDescription(caller->pc()->pending_local_description())
          .release());

  // SetLocalDescription(), implicitly creating an answer.
  auto callee_set_local_description_observer =
      MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetLocalDescription(
      callee_set_local_description_observer.get());
  EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
                   kWaitTimeout);
  // Chaining guarantees SetRemoteDescription() happened before
  // SetLocalDescription().
  EXPECT_TRUE(callee_set_remote_description_observer->called());
  EXPECT_TRUE(callee->pc()->current_local_description());

  // SetRemoteDescription(answer)
  auto caller_set_remote_description_observer =
      MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetRemoteDescription(
      caller_set_remote_description_observer.get(),
      CloneSessionDescription(callee->pc()->current_local_description())
          .release());
  EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
                   kWaitTimeout);

  EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
  EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer.get());

  // The operation should fail asynchronously.
  EXPECT_FALSE(observer->called());
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_FALSE(observer->result());
  // This did not affect the signaling state.
  EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
  EXPECT_EQ(
      "SetLocalDescription failed to create session description - "
      "SetLocalDescription called when PeerConnection is closed.",
      observer->error());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller->pc()->Close();

  // The operation should fail asynchronously.
  EXPECT_FALSE(observer->called());
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_FALSE(observer->result());
  // This did not affect the signaling state.
  EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
  EXPECT_EQ(
      "SetLocalDescription failed to create session description - "
      "CreateOffer failed because the session was shut down",
      observer->error());
}

TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
  auto caller = CreatePeerConnection();

  // Call setRemoteDescription with a m= line we don't understand.
  std::string sdp =
      "v=0\r\n"
      "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=bogus 9 FOO 0 8\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=mid:bogusmid\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  // Assert we respond back with something meaningful.
  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  EXPECT_NE(answer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported(),
            nullptr);
  EXPECT_EQ(answer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported()
                ->media_type(),
            "bogus");
  EXPECT_TRUE(answer->description()->contents()[0].rejected);
  EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
  EXPECT_EQ(
      answer->description()->contents()[0].media_description()->protocol(),
      "FOO");
  EXPECT_FALSE(
      answer->description()->contents()[0].media_description()->has_codecs());

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));

  // Assert we keep this in susequent offers.
  auto offer = caller->CreateOffer();
  EXPECT_EQ(offer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported()
                ->media_type(),
            "bogus");
  EXPECT_TRUE(offer->description()->contents()[0].rejected);
  EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
            "FOO");
  EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
  EXPECT_FALSE(
      offer->description()->contents()[0].media_description()->has_codecs());
  EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
}

TEST_P(PeerConnectionSignalingTest, ReceiveFlexFec) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=group:BUNDLE 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102 122\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=rtpmap:122 flexfec-03/90000\r\n"
      "a=fmtp:122 repair-window=10000000\r\n"
      "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
      "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  ASSERT_NE(answer->description()->contents()[0].media_description(), nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  ASSERT_EQ(codecs.size(), 2u);
  EXPECT_EQ(codecs[1].name, "flexfec-03");

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
}

TEST_P(PeerConnectionSignalingTest, ReceiveFlexFecReoffer) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=group:BUNDLE 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102 35\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=rtpmap:35 flexfec-03/90000\r\n"
      "a=fmtp:35 repair-window=10000000\r\n"
      "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
      "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  ASSERT_NE(answer->description()->contents()[0].media_description(), nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  ASSERT_EQ(codecs.size(), 2u);
  EXPECT_EQ(codecs[1].name, "flexfec-03");
  EXPECT_EQ(codecs[1].id, 35);

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));

  // This generates a collision for AV1 which needs to be remapped.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  auto offer_codecs = offer->description()
                          ->contents()[0]
                          .media_description()
                          ->codecs();
  auto flexfec_it = std::find_if(
      offer_codecs.begin(), offer_codecs.end(),
      [](const cricket::Codec& codec) { return codec.name == "flexfec-03"; });
  ASSERT_EQ(flexfec_it->id, 35);
  auto av1_it = std::find_if(
      offer_codecs.begin(), offer_codecs.end(),
      [](const cricket::Codec& codec) { return codec.name == "AV1"; });
  if (av1_it != offer_codecs.end()) {
    ASSERT_NE(av1_it->id, 35);
  }
}

TEST_P(PeerConnectionSignalingTest, MidAttributeMaxLength) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      // Too long mid attribute.
      "a=mid:0123456789012345678901234567890123\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_FALSE(caller->SetRemoteDescription(std::move(remote_description)));
}

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

class PeerConnectionSignalingUnifiedPlanTest
    : public PeerConnectionSignalingBaseTest {
 protected:
  PeerConnectionSignalingUnifiedPlanTest()
      : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
};

// We verify that SetLocalDescription() executed immediately by verifying that
// the transceiver mid values got assigned. SLD executing immeditately is not
// unique to Unified Plan, but the transceivers used to verify this are only
// available in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // By not waiting for the observer's callback we can verify that the operation
  // executed immediately. The old observer is invoked in a posted message, so
  // waiting for it would not ensure synchronicity.
  RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
  caller->pc()->SetLocalDescription(
      rtc::make_ref_counted<MockSetSessionDescriptionObserver>().get(),
      offer.release());
  EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // Verify that mids were assigned without waiting for the observer. (However,
  // the new observer should also be invoked synchronously - as is ensured by
  // other tests.)
  RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
  caller->pc()->SetLocalDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetLocalDescriptionObserver>());
  EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto offer_observer =
      rtc::make_ref_counted<ExecuteFunctionOnCreateSessionDescriptionObserver>(
          [pc = caller->pc()](SessionDescriptionInterface* desc) {
            // By not waiting for the observer's callback we can verify that the
            // operation executed immediately.
            RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
            pc->SetLocalDescription(
                rtc::make_ref_counted<MockSetSessionDescriptionObserver>()
                    .get(),
                desc);
            EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
          });
  caller->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
  EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
}

// Test that transports are shown in the sender/receiver API after offer/answer.
// This only works in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       DtlsTransportsInstantiateInOfferAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_TRUE(HasDtlsTransport(caller));
  callee->SetRemoteDescription(std::move(offer));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  EXPECT_TRUE(HasDtlsTransport(callee));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_TRUE(HasDtlsTransport(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_EQ(1, NumberOfDtlsTransports(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       DtlsTransportsAreSeparateeWhenUnbundled) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  RTCOfferAnswerOptions unbundle_options;
  unbundle_options.use_rtp_mux = false;
  auto offer = caller->CreateOffer(unbundle_options);
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(callee));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       ShouldFireNegotiationNeededWhenNoChangesArePending) {
  auto caller = CreatePeerConnection();
  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
  auto caller = CreatePeerConnection();
  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());

  auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
  // For this test to work, the operation has to be pending, i.e. the observer
  // has not yet been invoked.
  EXPECT_FALSE(observer->called());
  // Because the Operations Chain is not empty, the event is now suppressed.
  EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
  caller->observer()->clear_latest_negotiation_needed_event();

  // When the Operations Chain becomes empty again, a new negotiation needed
  // event will be generated that is not suppressed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());

  // Change signaling state (to "have-remote-offer") by setting a remote offer.
  callee->SetRemoteDescription(std::move(offer));
  // Because the signaling state is not "stable", the event is now suppressed.
  EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
      callee->observer()->latest_negotiation_needed_event()));
  callee->observer()->clear_latest_negotiation_needed_event();

  // Upon rolling back to "stable", a new negotiation needed event will be
  // generated that is not suppressed.
  callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
      callee->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest, RtxReofferApt) {
  auto callee = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(callee->SetRemoteDescription(std::move(remote_description)));

  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  EXPECT_TRUE(
      callee->SetLocalDescription(CloneSessionDescription(answer.get())));

  callee->pc()->GetTransceivers()[0]->StopStandard();
  auto reoffer = callee->CreateOffer(RTCOfferAnswerOptions());
  auto codecs = reoffer->description()
                    ->contents()[0]
                    .media_description()
                    ->codecs();
  ASSERT_GT(codecs.size(), 2u);
  EXPECT_EQ(codecs[0].name, "VP8");
  EXPECT_EQ(codecs[1].name, "rtx");
  auto apt_it = codecs[1].params.find("apt");
  ASSERT_NE(apt_it, codecs[1].params.end());
  // The apt should match the id from the remote offer.
  EXPECT_EQ(apt_it->second, rtc::ToString(codecs[0].id));
  EXPECT_EQ(apt_it->second, "102");
}

}  // namespace webrtc
