/*
 *  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 <set>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#include "api/audio/audio_mixer.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/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
#include "media/base/codec.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.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/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::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(),
        CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
        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_PRED_FORMAT2(AssertStartsWith, 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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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_PRED_FORMAT2(
        AssertStartsWith, error,
        "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<webrtc::SessionDescriptionInterface> remote_description =
      webrtc::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<webrtc::SessionDescriptionInterface> remote_description =
      webrtc::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()->as_video(),
      nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->as_video()
                    ->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<webrtc::SessionDescriptionInterface> remote_description =
      webrtc::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()->as_video(),
      nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->as_video()
                    ->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()
                          ->as_video()
                          ->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<webrtc::SessionDescriptionInterface> remote_description =
      webrtc::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<webrtc::SessionDescriptionInterface> remote_description =
      webrtc::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()
                    ->as_video()
                    ->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
