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

#include "api/peer_connection_interface.h"

#include <climits>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "api/audio/audio_device.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/crypto/crypto_options.h"
#include "api/data_channel_interface.h"
#include "api/enable_media_with_defaults.h"
#include "api/jsep.h"
#include "api/make_ref_counted.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/rtc_error.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/rtc_event_log/rtc_event_log_factory.h"
#include "api/rtc_event_log_output.h"
#include "api/rtp_parameters.h"
#include "api/rtp_receiver_interface.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_direction.h"
#include "api/scoped_refptr.h"
#include "api/sctp_transport_interface.h"
#include "api/test/rtc_error_matchers.h"
#include "api/transport/bitrate_settings.h"
#include "api/transport/enums.h"
#include "api/units/time_delta.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 "media/base/media_config.h"
#include "media/base/stream_params.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "p2p/test/fake_port_allocator.h"
#include "pc/audio_track.h"
#include "pc/media_session.h"
#include "pc/media_stream.h"
#include "pc/peer_connection.h"
#include "pc/peer_connection_factory.h"
#include "pc/rtp_media_utils.h"
#include "pc/rtp_sender.h"
#include "pc/rtp_sender_proxy.h"
#include "pc/session_description.h"
#include "pc/stream_collection.h"
#include "pc/test/fake_audio_capture_module.h"
#include "pc/test/fake_rtc_certificate_generator.h"
#include "pc/test/fake_video_track_source.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "pc/test/test_sdp_strings.h"
#include "pc/video_track.h"
#include "rtc_base/checks.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/socket_server.h"
#include "rtc_base/system/plan_b_only.h"
#include "rtc_base/thread.h"
#include "rtc_base/virtual_socket_server.h"
#include "rtc_base/weak_ptr.h"
#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/run_loop.h"
#include "test/wait_until.h"

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

namespace webrtc {
namespace {

using ::testing::Eq;
using ::testing::Exactly;
using ::testing::IsNull;
using ::testing::IsTrue;
using ::testing::NotNull;
using ::testing::SizeIs;
using ::testing::Values;

using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;

constexpr char kStreamId1[] = "local_stream_1";
constexpr char kStreamId2[] = "local_stream_2";
constexpr char kStreamId3[] = "local_stream_3";
constexpr int kDefaultStunPort = 3478;
constexpr char kStunAddressOnly[] = "stun:address";
constexpr char kStunInvalidPort[] = "stun:address:-1";
constexpr char kStunAddressPortAndMore1[] = "stun:address:port:more";
constexpr char kStunAddressPortAndMore2[] = "stun:address:port more";
constexpr char kTurnIceServerUri[] = "turn:turn.example.org";
constexpr char kTurnUsername[] = "user";
constexpr char kTurnPassword[] = "password";
constexpr char kTurnHostname[] = "turn.example.org";
constexpr uint32_t kTimeout = 10000U;

constexpr char kStreams[][8] = {"stream1", "stream2"};
constexpr char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
constexpr char kVideoTracks[][32] = {"videotrack0", "videotrack1"};

constexpr char kRecvonly[] = "recvonly";
constexpr char kSendrecv[] = "sendrecv";

// Reference SDP with a MediaStream with label "stream1" and audio track with
// id "audio_1" and a video track with id "video_1;
constexpr char kSdpStringWithStream1PlanB[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=ssrc:1 cname:stream1\r\n"
    "a=ssrc:1 msid:stream1 audiotrack0\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n"
    "a=ssrc:2 cname:stream1\r\n"
    "a=ssrc:2 msid:stream1 videotrack0\r\n";
// Same string as above but with the MID changed to the Unified Plan default and
// a=msid added. This is needed so that this SDP can be used as an answer for a
// Unified Plan offer.
constexpr char kSdpStringWithStream1UnifiedPlan[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:0\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=msid:stream1 audiotrack0\r\n"
    "a=ssrc:1 cname:stream1\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:1\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n"
    "a=msid:stream1 videotrack0\r\n"
    "a=ssrc:2 cname:stream1\r\n";

// Reference SDP with a MediaStream with label "stream1" and audio track with
// id "audio_1";
constexpr char kSdpStringWithStream1AudioTrackOnly[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=ssrc:1 cname:stream1\r\n"
    "a=ssrc:1 msid:stream1 audiotrack0\r\n"
    "a=rtcp-mux\r\n";

// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
// MediaStreams have one audio track and one video track.
// This uses MSID.
constexpr char kSdpStringWithStream1And2PlanB[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "a=msid-semantic: WMS stream1 stream2\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=ssrc:1 cname:stream1\r\n"
    "a=ssrc:1 msid:stream1 audiotrack0\r\n"
    "a=ssrc:3 cname:stream2\r\n"
    "a=ssrc:3 msid:stream2 audiotrack1\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/0\r\n"
    "a=ssrc:2 cname:stream1\r\n"
    "a=ssrc:2 msid:stream1 videotrack0\r\n"
    "a=ssrc:4 cname:stream2\r\n"
    "a=ssrc:4 msid:stream2 videotrack1\r\n";
constexpr char kSdpStringWithStream1And2UnifiedPlan[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "a=msid-semantic: WMS stream1 stream2\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:0\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=ssrc:1 cname:stream1\r\n"
    "a=ssrc:1 msid:stream1 audiotrack0\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:1\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/0\r\n"
    "a=ssrc:2 cname:stream1\r\n"
    "a=ssrc:2 msid:stream1 videotrack0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:2\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "a=ssrc:3 cname:stream2\r\n"
    "a=ssrc:3 msid:stream2 audiotrack1\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:3\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/0\r\n"
    "a=ssrc:4 cname:stream2\r\n"
    "a=ssrc:4 msid:stream2 videotrack1\r\n";

// Reference SDP without MediaStreams. Msid is not supported.
constexpr char kSdpStringWithoutStreams[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n";

// Reference SDP without MediaStreams. Msid is supported.
constexpr char kSdpStringWithMsidWithoutStreams[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "a=msid-semantic: WMS\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n";

// Reference SDP without MediaStreams and audio only.
constexpr char kSdpStringWithoutStreamsAudioOnly[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n";

// Reference SENDONLY SDP without MediaStreams. Msid is not supported.
constexpr char kSdpStringSendOnlyWithoutStreams[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=sendonly\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n"
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=sendonly\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n";

constexpr char kSdpStringInit[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=-\r\n"
    "t=0 0\r\n"
    "a=msid-semantic: WMS\r\n";

constexpr char kSdpStringAudio[] =
    "m=audio 1 RTP/AVPF 111\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:audio\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:111 OPUS/48000/2\r\n";

constexpr char kSdpStringVideo[] =
    "m=video 1 RTP/AVPF 120\r\n"
    "a=ice-ufrag:e5785931\r\n"
    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
    "a=mid:video\r\n"
    "a=sendrecv\r\n"
    "a=rtcp-mux\r\n"
    "a=rtpmap:120 VP8/90000\r\n";

constexpr char kSdpStringMs1Audio0[] =
    "a=ssrc:1 cname:stream1\r\n"
    "a=ssrc:1 msid:stream1 audiotrack0\r\n";

constexpr char kSdpStringMs1Video0[] =
    "a=ssrc:2 cname:stream1\r\n"
    "a=ssrc:2 msid:stream1 videotrack0\r\n";

constexpr char kSdpStringMs1Audio1[] =
    "a=ssrc:3 cname:stream1\r\n"
    "a=ssrc:3 msid:stream1 audiotrack1\r\n";

constexpr char kSdpStringMs1Video1[] =
    "a=ssrc:4 cname:stream1\r\n"
    "a=ssrc:4 msid:stream1 videotrack1\r\n";

class RtcEventLogOutputNull final : public RtcEventLogOutput {
 public:
  bool IsActive() const override { return true; }
  bool Write(const absl::string_view /*output*/) override { return true; }
};

// Gets the first ssrc of given content type from the ContentInfo.
bool GetFirstSsrc(const ContentInfo* content_info, int* ssrc) {
  if (!content_info || !ssrc) {
    return false;
  }
  const MediaContentDescription* media_desc = content_info->media_description();
  if (!media_desc || media_desc->streams().empty()) {
    return false;
  }
  *ssrc = media_desc->streams().begin()->first_ssrc();
  return true;
}

// Get the ufrags out of an SDP blob. Useful for testing ICE restart
// behavior.
std::vector<std::string> GetUfrags(const SessionDescriptionInterface* desc) {
  std::vector<std::string> ufrags;
  for (const TransportInfo& info : desc->description()->transport_infos()) {
    ufrags.push_back(info.description.ice_ufrag);
  }
  return ufrags;
}

void SetSsrcToZero(std::string* sdp) {
  const char kSdpSsrcAtribute[] = "a=ssrc:";
  const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
  size_t ssrc_pos = 0;
  while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
         std::string::npos) {
    size_t end_ssrc = sdp->find(" ", ssrc_pos);
    sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
    ssrc_pos = end_ssrc;
  }
}

// Check if `streams` contains the specified track.
bool ContainsTrack(const std::vector<StreamParams>& streams,
                   const std::string& stream_id,
                   const std::string& track_id) {
  for (const StreamParams& params : streams) {
    if (params.first_stream_id() == stream_id && params.id == track_id) {
      return true;
    }
  }
  return false;
}

// Check if `senders` contains the specified sender, by id.
bool ContainsSender(
    const std::vector<scoped_refptr<RtpSenderInterface>>& senders,
    const std::string& id) {
  for (const auto& sender : senders) {
    if (sender->id() == id) {
      return true;
    }
  }
  return false;
}

// Check if `senders` contains the specified sender, by id and stream id.
bool ContainsSender(
    const std::vector<scoped_refptr<RtpSenderInterface>>& senders,
    const std::string& id,
    const std::string& stream_id) {
  for (const auto& sender : senders) {
    if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
      return true;
    }
  }
  return false;
}

// Create a collection of streams.
// CreateStreamCollection(1) creates a collection that
// correspond to kSdpStringWithStream1.
// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
scoped_refptr<StreamCollection> CreateStreamCollection(int number_of_streams,
                                                       int tracks_per_stream,
                                                       Thread* worker_thread) {
  scoped_refptr<StreamCollection> local_collection(StreamCollection::Create());

  for (int i = 0; i < number_of_streams; ++i) {
    scoped_refptr<MediaStreamInterface> stream(
        MediaStream::Create(kStreams[i]));

    for (int j = 0; j < tracks_per_stream; ++j) {
      // Add a local audio track.
      scoped_refptr<AudioTrackInterface> audio_track(
          AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j], nullptr));
      stream->AddTrack(audio_track);

      // Add a local video track.
      scoped_refptr<VideoTrackInterface> video_track(
          VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
                             FakeVideoTrackSource::Create(), worker_thread));
      stream->AddTrack(video_track);
    }

    local_collection->AddStream(stream);
  }
  return local_collection;
}

// Check equality of StreamCollections.
bool CompareStreamCollections(StreamCollectionInterface* s1,
                              StreamCollectionInterface* s2) {
  if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
    return false;
  }

  for (size_t i = 0; i != s1->count(); ++i) {
    if (s1->at(i)->id() != s2->at(i)->id()) {
      return false;
    }
    AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
    AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
    VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
    VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();

    if (audio_tracks1.size() != audio_tracks2.size()) {
      return false;
    }
    for (size_t j = 0; j != audio_tracks1.size(); ++j) {
      if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
        return false;
      }
    }
    if (video_tracks1.size() != video_tracks2.size()) {
      return false;
    }
    for (size_t j = 0; j != video_tracks1.size(); ++j) {
      if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
        return false;
      }
    }
  }
  return true;
}

// Helper class to test Observer.
class MockTrackObserver : public ObserverInterface {
 public:
  explicit MockTrackObserver(NotifierInterface* notifier)
      : notifier_(notifier) {
    notifier_->RegisterObserver(this);
  }

  ~MockTrackObserver() override { Unregister(); }

  void Unregister() {
    if (notifier_) {
      notifier_->UnregisterObserver(this);
      notifier_ = nullptr;
    }
  }

  MOCK_METHOD(void, OnChanged, (), (override));

 private:
  NotifierInterface* notifier_;
};

// The PeerConnectionMediaConfig tests below verify that configuration and
// constraints are propagated into the PeerConnection's MediaConfig. These
// settings are intended for MediaChannel constructors, but that is not
// exercised by these unittest.
class PeerConnectionFactoryForTest : public PeerConnectionFactory {
 public:
  static scoped_refptr<PeerConnectionFactoryForTest>
  CreatePeerConnectionFactoryForTest(Thread* network_thread,
                                     Thread* worker_thread) {
    PeerConnectionFactoryDependencies dependencies;
    dependencies.worker_thread = worker_thread;
    dependencies.network_thread = network_thread;
    dependencies.signaling_thread = Thread::Current();
    // Use fake audio device module since we're only testing the interface
    // level, and using a real one could make tests flaky when run in parallel.
    dependencies.adm = FakeAudioCaptureModule::Create();
    EnableMediaWithDefaults(dependencies);
    dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>();

    return make_ref_counted<PeerConnectionFactoryForTest>(
        std::move(dependencies));
  }

  using PeerConnectionFactory::PeerConnectionFactory;

 private:
  scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
};

// TODO(steveanton): Convert to use the new PeerConnectionWrapper.
class PeerConnectionInterfaceBaseTest : public ::testing::Test {
 protected:
  explicit PeerConnectionInterfaceBaseTest(SdpSemantics sdp_semantics)
      : vss_(new VirtualSocketServer()),
        main_(vss_.get()),
        sdp_semantics_(sdp_semantics) {
#ifdef WEBRTC_ANDROID
    InitializeAndroidObjects();
#endif
  }

  void SetUp() override {
    // Use fake audio capture module since we're only testing the interface
    // level, and using a real one could make tests flaky when run in parallel.
    fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
    network_thread_ = Thread::CreateWithSocketServer();
    network_thread_->SetName("NetworkThread", nullptr);
    ASSERT_TRUE(network_thread_->Start());
    worker_thread_ = Thread::Create();
    worker_thread_->SetName("WorkerThread", nullptr);
    ASSERT_TRUE(worker_thread_->Start());

    pc_factory_ = CreatePeerConnectionFactory(
        network_thread_.get(), worker_thread_.get(), Thread::Current(),
        scoped_refptr<AudioDeviceModule>(fake_audio_capture_module_),
        CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
        std::make_unique<VideoEncoderFactoryTemplate<
            LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter,
            OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>(),
        std::make_unique<VideoDecoderFactoryTemplate<
            LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter,
            OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(),
        nullptr /* audio_mixer */, nullptr /* audio_processing */);
    ASSERT_TRUE(pc_factory_);
  }

  void TearDown() override {
    if (pc_) {
      pc_->Close();
      ReleasePeerConnection();
    }

    network_thread_->BlockingCall(
        [&] { ASSERT_THAT(port_allocator_, IsNull()); });
  }

  void CreatePeerConnection() {
    CreatePeerConnection(PeerConnectionInterface::RTCConfiguration());
  }

  // DTLS does not work in a loopback call, so is disabled for many
  // tests in this file.
  void CreatePeerConnectionWithoutDtls() {
    RTCConfiguration config;
    PeerConnectionFactoryInterface::Options options;
    options.disable_encryption = true;
    pc_factory_->SetOptions(options);
    CreatePeerConnection(config);
    options.disable_encryption = false;
    pc_factory_->SetOptions(options);
  }

  void CreatePeerConnectionWithIceTransportsType(
      PeerConnectionInterface::IceTransportsType type) {
    PeerConnectionInterface::RTCConfiguration config;
    config.type = type;
    return CreatePeerConnection(config);
  }

  void CreatePeerConnectionWithIceServer(const std::string& uri,
                                         const std::string& username,
                                         const std::string& password) {
    PeerConnectionInterface::RTCConfiguration config;
    PeerConnectionInterface::IceServer server;
    server.uri = uri;
    server.username = username;
    server.password = password;
    config.servers.push_back(server);
    CreatePeerConnection(config);
  }

  void CreatePeerConnection(const RTCConfiguration& config) {
    if (pc_) {
      pc_->Close();
      ReleasePeerConnection();
    }
    network_thread_->BlockingCall(
        [&] { ASSERT_THAT(port_allocator_, IsNull()); });

    std::unique_ptr<FakePortAllocator> port_allocator =
        network_thread_->BlockingCall([&] {
          auto allocator = std::make_unique<FakePortAllocator>(
              CreateTestEnvironment(), network_thread_->socketserver());
          port_allocator_ = allocator->NewWeakPtr();
          return allocator;
        });

    // Create certificate generator unless DTLS constraint is explicitly set to
    // false.
    std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator;

    // These won't be used if encryption is turned off, but that's harmless.
    fake_certificate_generator_ = new FakeRTCCertificateGenerator();
    cert_generator.reset(fake_certificate_generator_);

    RTCConfiguration modified_config = config;
    modified_config.sdp_semantics = sdp_semantics_;
    PeerConnectionDependencies pc_dependencies(&observer_);
    pc_dependencies.cert_generator = std::move(cert_generator);
    pc_dependencies.allocator = std::move(port_allocator);
    auto result = pc_factory_->CreatePeerConnectionOrError(
        modified_config, std::move(pc_dependencies));
    ASSERT_TRUE(result.ok());
    pc_ = result.MoveValue();
    observer_.SetPeerConnectionInterface(pc_.get());
    EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
  }

  void CreatePeerConnectionExpectFail(const std::string& uri) {
    PeerConnectionInterface::RTCConfiguration config;
    PeerConnectionInterface::IceServer server;
    server.uri = uri;
    config.servers.push_back(server);
    config.sdp_semantics = sdp_semantics_;
    PeerConnectionDependencies pc_dependencies(&observer_);
    auto result = pc_factory_->CreatePeerConnectionOrError(
        config, std::move(pc_dependencies));
    EXPECT_FALSE(result.ok());
  }

  void CreatePeerConnectionExpectFail(
      PeerConnectionInterface::RTCConfiguration config) {
    PeerConnectionInterface::IceServer server;
    server.uri = kTurnIceServerUri;
    server.password = kTurnPassword;
    config.servers.push_back(server);
    config.sdp_semantics = sdp_semantics_;
    PeerConnectionDependencies pc_dependencies(&observer_);
    auto result = pc_factory_->CreatePeerConnectionOrError(
        config, std::move(pc_dependencies));
    EXPECT_FALSE(result.ok());
  }

  void CreatePeerConnectionWithDifferentConfigurations() {
    CreatePeerConnectionWithIceServer(kStunAddressOnly, "", "");
    network_thread_->BlockingCall([&] {
      EXPECT_EQ(1u, port_allocator_->stun_servers().size());
      EXPECT_EQ(0u, port_allocator_->turn_servers().size());
      EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
      EXPECT_EQ(kDefaultStunPort,
                port_allocator_->stun_servers().begin()->port());
    });

    CreatePeerConnectionExpectFail(kStunInvalidPort);
    CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
    CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);

    CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnUsername,
                                      kTurnPassword);
    network_thread_->BlockingCall([&] {
      EXPECT_EQ(0u, port_allocator_->stun_servers().size());
      EXPECT_EQ(1u, port_allocator_->turn_servers().size());
      EXPECT_EQ(kTurnUsername,
                port_allocator_->turn_servers()[0].credentials.username);
      EXPECT_EQ(kTurnPassword,
                port_allocator_->turn_servers()[0].credentials.password);
      EXPECT_EQ(kTurnHostname,
                port_allocator_->turn_servers()[0].ports[0].address.hostname());
    });
  }

  void ReleasePeerConnection() {
    pc_ = nullptr;
    observer_.SetPeerConnectionInterface(nullptr);
  }

  scoped_refptr<VideoTrackInterface> CreateVideoTrack(
      const std::string& label) {
    return pc_factory_->CreateVideoTrack(FakeVideoTrackSource::Create(), label);
  }

  void AddVideoTrack(const std::string& track_label,
                     const std::vector<std::string>& stream_ids = {}) {
    auto sender_or_error =
        pc_->AddTrack(CreateVideoTrack(track_label), stream_ids);
    ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
  }

  void AddVideoStream(const std::string& label) {
    scoped_refptr<MediaStreamInterface> stream(
        pc_factory_->CreateLocalMediaStream(label));
    stream->AddTrack(CreateVideoTrack(label + "v0"));
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    ASSERT_TRUE(pc_->AddStream(stream.get()));
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
  }

  scoped_refptr<AudioTrackInterface> CreateAudioTrack(
      const std::string& label) {
    return pc_factory_->CreateAudioTrack(label, nullptr);
  }

  void AddAudioTrack(const std::string& track_label,
                     const std::vector<std::string>& stream_ids = {}) {
    auto sender_or_error =
        pc_->AddTrack(CreateAudioTrack(track_label), stream_ids);
    ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
  }

  void AddAudioStream(const std::string& label) {
    scoped_refptr<MediaStreamInterface> stream(
        pc_factory_->CreateLocalMediaStream(label));
    stream->AddTrack(CreateAudioTrack(label + "a0"));
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    ASSERT_TRUE(pc_->AddStream(stream.get()));
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
  }

  void AddAudioVideoStream(const std::string& stream_id,
                           const std::string& audio_track_label,
                           const std::string& video_track_label) {
    // Create a local stream.
    scoped_refptr<MediaStreamInterface> stream(
        pc_factory_->CreateLocalMediaStream(stream_id));
    stream->AddTrack(CreateAudioTrack(audio_track_label));
    stream->AddTrack(CreateVideoTrack(video_track_label));
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    ASSERT_TRUE(pc_->AddStream(stream.get()));
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
  }

  scoped_refptr<RtpReceiverInterface> GetFirstReceiverOfType(
      MediaType media_type) {
    for (auto receiver : pc_->GetReceivers()) {
      if (receiver->media_type() == media_type) {
        return receiver;
      }
    }
    return nullptr;
  }

  bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
                           const RTCOfferAnswerOptions* options,
                           bool offer) {
    auto observer = make_ref_counted<MockCreateSessionDescriptionObserver>();
    if (offer) {
      pc_->CreateOffer(observer.get(),
                       options ? *options : RTCOfferAnswerOptions());
    } else {
      pc_->CreateAnswer(observer.get(),
                        options ? *options : RTCOfferAnswerOptions());
    }
    EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue(),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
    *desc = observer->MoveDescription();
    return observer->result();
  }

  bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
                     const RTCOfferAnswerOptions* options) {
    return DoCreateOfferAnswer(desc, options, true);
  }

  bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
                      const RTCOfferAnswerOptions* options) {
    return DoCreateOfferAnswer(desc, options, false);
  }

  bool DoSetSessionDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      bool local) {
    auto observer = make_ref_counted<MockSetSessionDescriptionObserver>();
    if (local) {
      pc_->SetLocalDescription(observer.get(), desc.release());
    } else {
      pc_->SetRemoteDescription(observer.get(), desc.release());
    }
    if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
      EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue(),
                            {.timeout = TimeDelta::Millis(kTimeout)}),
                  IsRtcOk());
    }
    return observer->result();
  }

  bool DoSetLocalDescription(
      std::unique_ptr<SessionDescriptionInterface> desc) {
    return DoSetSessionDescription(std::move(desc), true);
  }

  bool DoSetRemoteDescription(
      std::unique_ptr<SessionDescriptionInterface> desc) {
    return DoSetSessionDescription(std::move(desc), false);
  }

  // Calls PeerConnection::GetStats and check the return value.
  // It does not verify the values in the StatReports since a RTCP packet might
  // be required.
  bool DoGetStats(MediaStreamTrackInterface* track) {
    auto observer = make_ref_counted<MockStatsObserver>();
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    bool result =
        pc_->GetStats(observer.get(), track,
                      PeerConnectionInterface::kStatsOutputLevelStandard);
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
    if (!result)
      return false;
    EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue(),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
    return observer->called();
  }

  // Call the standards-compliant GetStats function.
  bool DoGetRTCStats() {
    auto callback = make_ref_counted<MockRTCStatsCollectorCallback>();
    pc_->GetStats(callback.get());
    EXPECT_THAT(WaitUntil([&] { return callback->called(); }, IsTrue(),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
    return callback->called();
  }

  void InitiateCall() {
    CreatePeerConnectionWithoutDtls();
    // Create a local stream with audio&video tracks.
    if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
      AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
    } else {
      // Unified Plan does not support AddStream, so just add an audio and video
      // track.
      AddAudioTrack(kAudioTracks[0], {kStreamId1});
      AddVideoTrack(kVideoTracks[0], {kStreamId1});
    }
    CreateOfferReceiveAnswer();
  }

  // Verify that RTP Header extensions has been negotiated for audio and video.
  void VerifyRemoteRtpHeaderExtensions() {
    const MediaContentDescription* desc = GetFirstAudioContentDescription(
        pc_->remote_description()->description());
    ASSERT_TRUE(desc != nullptr);
    EXPECT_GT(desc->rtp_header_extensions().size(), 0u);

    desc = GetFirstVideoContentDescription(
        pc_->remote_description()->description());
    ASSERT_TRUE(desc != nullptr);
    EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
  }

  void CreateOfferAsRemoteDescription() {
    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    std::string sdp;
    EXPECT_TRUE(offer->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> remote_offer(
        CreateSessionDescription(SdpType::kOffer, sdp));
    EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
  }

  void CreateAndSetRemoteOffer(const std::string& sdp) {
    std::unique_ptr<SessionDescriptionInterface> remote_offer(
        CreateSessionDescription(SdpType::kOffer, sdp));
    EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
  }

  void CreateAnswerAsLocalDescription() {
    std::unique_ptr<SessionDescriptionInterface> answer;
    ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));

    // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
    // audio codec change, even if the parameter has nothing to do with
    // receiving. Not all parameters are serialized to SDP.
    // Since CreatePrAnswerAsLocalDescription serialize/deserialize
    // the SessionDescription, it is necessary to do that here to in order to
    // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
    // https://code.google.com/p/webrtc/issues/detail?id=1356
    std::string sdp;
    EXPECT_TRUE(answer->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> new_answer(
        CreateSessionDescription(SdpType::kAnswer, sdp));
    EXPECT_TRUE(DoSetLocalDescription(std::move(new_answer)));
    EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
  }

  void CreatePrAnswerAsLocalDescription() {
    std::unique_ptr<SessionDescriptionInterface> answer;
    ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));

    std::string sdp;
    EXPECT_TRUE(answer->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> pr_answer(
        CreateSessionDescription(SdpType::kPrAnswer, sdp));
    EXPECT_TRUE(DoSetLocalDescription(std::move(pr_answer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
  }

  void CreateOfferReceiveAnswer() {
    CreateOfferAsLocalDescription();
    std::unique_ptr<SessionDescriptionInterface> offer =
        pc_->local_description()->Clone();
    // Adapts the offer so that it can serve as an answer.
    // This test does not use DTLS so direcetion does not have
    // to be adapted in a similar way.
    for (auto& content : offer->description()->contents()) {
      MediaContentDescription* media_description = content.media_description();
      media_description->set_direction(
          RtpTransceiverDirectionReversed(media_description->direction()));
    }
    std::string sdp;
    EXPECT_TRUE(offer->ToString(&sdp));
    CreateAnswerAsRemoteDescription(sdp);
  }

  void CreateOfferAsLocalDescription() {
    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
    // audio codec change, even if the parameter has nothing to do with
    // receiving. Not all parameters are serialized to SDP.
    // Since CreatePrAnswerAsLocalDescription serialize/deserialize
    // the SessionDescription, it is necessary to do that here to in order to
    // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
    // https://code.google.com/p/webrtc/issues/detail?id=1356
    std::string sdp;
    EXPECT_TRUE(offer->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> new_offer(
        CreateSessionDescription(SdpType::kOffer, sdp));

    EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
    // Wait for the ice_complete message, so that SDP will have candidates.
    EXPECT_THAT(WaitUntil([&] { return observer_.ice_gathering_complete_; },
                          IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
  }

  void CreateAnswerAsRemoteDescription(const std::string& sdp) {
    std::unique_ptr<SessionDescriptionInterface> answer(
        CreateSessionDescription(SdpType::kAnswer, sdp));
    ASSERT_THAT(answer, NotNull());
    EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
    EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
  }

  void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
    std::unique_ptr<SessionDescriptionInterface> pr_answer(
        CreateSessionDescription(SdpType::kPrAnswer, sdp));
    ASSERT_TRUE(pr_answer);
    EXPECT_TRUE(DoSetRemoteDescription(std::move(pr_answer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
    std::unique_ptr<SessionDescriptionInterface> answer(
        CreateSessionDescription(SdpType::kAnswer, sdp));
    ASSERT_THAT(answer, NotNull());
    EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
    EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
  }

  // Waits until a remote stream with the given id is signaled. This helper
  // function will verify both OnAddTrack and OnAddStream (Plan B only) are
  // called with the given stream id and expected number of tracks.
  RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
  void WaitAndVerifyOnAddStream(const std::string& stream_id,
                                int expected_num_tracks) {
    // Verify that both OnAddStream and OnAddTrack are called.
    EXPECT_THAT(
        WaitUntil([&] { return observer_.GetLastAddedStreamId(); },
                  Eq(stream_id), {.timeout = TimeDelta::Millis(kTimeout)}),
        IsRtcOk());
    EXPECT_THAT(
        WaitUntil(
            [&] { return observer_.CountAddTrackEventsForStream(stream_id); },
            Eq(expected_num_tracks), {.timeout = TimeDelta::Millis(kTimeout)}),
        IsRtcOk());
  }
  RTC_ALLOW_PLAN_B_DEPRECATION_END()

  // Creates an offer and applies it as a local session description.
  // Creates an answer with the same SDP an the offer but removes all lines
  // that start with a:ssrc"
  void CreateOfferReceiveAnswerWithoutSsrc() {
    CreateOfferAsLocalDescription();
    std::string sdp;
    EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
    SetSsrcToZero(&sdp);
    CreateAnswerAsRemoteDescription(sdp);
  }

  // This function creates a MediaStream with label kStreams[0] and
  // `number_of_audio_tracks` and `number_of_video_tracks` tracks and the
  // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
  // is returned and the MediaStream is stored in
  // `reference_collection_`
  std::unique_ptr<SessionDescriptionInterface>
  CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
                                       size_t number_of_video_tracks) {
    EXPECT_LE(number_of_audio_tracks, 2u);
    EXPECT_LE(number_of_video_tracks, 2u);

    reference_collection_ = StreamCollection::Create();
    std::string sdp_ms1 = std::string(kSdpStringInit);

    std::string mediastream_id = kStreams[0];

    scoped_refptr<MediaStreamInterface> stream(
        MediaStream::Create(mediastream_id));
    reference_collection_->AddStream(stream);

    if (number_of_audio_tracks > 0) {
      sdp_ms1 += std::string(kSdpStringAudio);
      sdp_ms1 += std::string(kSdpStringMs1Audio0);
      AddAudioTrack(kAudioTracks[0], stream.get());
    }
    if (number_of_audio_tracks > 1) {
      sdp_ms1 += kSdpStringMs1Audio1;
      AddAudioTrack(kAudioTracks[1], stream.get());
    }

    if (number_of_video_tracks > 0) {
      sdp_ms1 += std::string(kSdpStringVideo);
      sdp_ms1 += std::string(kSdpStringMs1Video0);
      AddVideoTrack(kVideoTracks[0], stream.get());
    }
    if (number_of_video_tracks > 1) {
      sdp_ms1 += kSdpStringMs1Video1;
      AddVideoTrack(kVideoTracks[1], stream.get());
    }

    return std::unique_ptr<SessionDescriptionInterface>(
        CreateSessionDescription(SdpType::kOffer, sdp_ms1));
  }

  void AddAudioTrack(const std::string& track_id,
                     MediaStreamInterface* stream) {
    scoped_refptr<AudioTrackInterface> audio_track(
        AudioTrack::Create(track_id, nullptr));
    ASSERT_TRUE(stream->AddTrack(audio_track));
  }

  void AddVideoTrack(const std::string& track_id,
                     MediaStreamInterface* stream) {
    scoped_refptr<VideoTrackInterface> video_track(VideoTrack::Create(
        track_id, FakeVideoTrackSource::Create(), worker_thread_.get()));
    ASSERT_TRUE(stream->AddTrack(video_track));
  }

  std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioTrack() {
    CreatePeerConnectionWithoutDtls();
    AddAudioTrack(kAudioTracks[0]);
    std::unique_ptr<SessionDescriptionInterface> offer;
    EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
    return offer;
  }

  std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
    CreatePeerConnectionWithoutDtls();
    AddAudioStream(kStreamId1);
    std::unique_ptr<SessionDescriptionInterface> offer;
    EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
    return offer;
  }

  std::unique_ptr<SessionDescriptionInterface> CreateAnswerWithOneAudioTrack() {
    EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioTrack()));
    std::unique_ptr<SessionDescriptionInterface> answer;
    EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
    return answer;
  }

  std::unique_ptr<SessionDescriptionInterface>
  CreateAnswerWithOneAudioStream() {
    EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioStream()));
    std::unique_ptr<SessionDescriptionInterface> answer;
    EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
    return answer;
  }

  const std::string& GetFirstAudioStreamCname(
      const SessionDescriptionInterface* desc) {
    const AudioContentDescription* audio_desc =
        GetFirstAudioContentDescription(desc->description());
    return audio_desc->streams()[0].cname;
  }

  std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOptions(
      const RTCOfferAnswerOptions& offer_answer_options) {
    RTC_DCHECK(pc_);
    auto observer = make_ref_counted<MockCreateSessionDescriptionObserver>();
    pc_->CreateOffer(observer.get(), offer_answer_options);
    EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue(),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
    return observer->MoveDescription();
  }

  void CreateOfferWithOptionsAsRemoteDescription(
      std::unique_ptr<SessionDescriptionInterface>* desc,
      const RTCOfferAnswerOptions& offer_answer_options) {
    *desc = CreateOfferWithOptions(offer_answer_options);
    ASSERT_TRUE(desc != nullptr);
    std::string sdp;
    EXPECT_TRUE((*desc)->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> remote_offer(
        CreateSessionDescription(SdpType::kOffer, sdp));
    EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
  }

  void CreateOfferWithOptionsAsLocalDescription(
      std::unique_ptr<SessionDescriptionInterface>* desc,
      const RTCOfferAnswerOptions& offer_answer_options) {
    *desc = CreateOfferWithOptions(offer_answer_options);
    ASSERT_TRUE(desc != nullptr);
    std::string sdp;
    EXPECT_TRUE((*desc)->ToString(&sdp));
    std::unique_ptr<SessionDescriptionInterface> new_offer(
        CreateSessionDescription(SdpType::kOffer, sdp));

    EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
    EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
  }

  bool HasCNCodecs(const ContentInfo* content) {
    RTC_DCHECK(content);
    RTC_DCHECK(content->media_description());
    for (const Codec& codec : content->media_description()->codecs()) {
      if (codec.name == "CN") {
        return true;
      }
    }
    return false;
  }

  const char* GetSdpStringWithStream1() const {
    if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
      return kSdpStringWithStream1PlanB;
    } else {
      return kSdpStringWithStream1UnifiedPlan;
    }
  }

  const char* GetSdpStringWithStream1And2() const {
    if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
      return kSdpStringWithStream1And2PlanB;
    } else {
      return kSdpStringWithStream1And2UnifiedPlan;
    }
  }

  SocketServer* socket_server() const { return vss_.get(); }

  std::unique_ptr<VirtualSocketServer> vss_;
  test::RunLoop main_;
  std::unique_ptr<Thread> network_thread_;
  std::unique_ptr<Thread> worker_thread_;
  scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
  WeakPtr<FakePortAllocator> port_allocator_;
  FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
  scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
  scoped_refptr<PeerConnectionInterface> pc_;
  MockPeerConnectionObserver observer_;
  scoped_refptr<StreamCollection> reference_collection_;
  const SdpSemantics sdp_semantics_;
};

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

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Plan B specific tests.
// Note - since the class is PLAN_B_ONLY, instances must be bracketed by
// RTC_ALLOW_PLAN_B_DEPRECATION macros.
class PLAN_B_ONLY PeerConnectionInterfaceTestPlanB
    : public PeerConnectionInterfaceBaseTest {
 protected:
  PeerConnectionInterfaceTestPlanB()
      : PeerConnectionInterfaceBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
};
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Generate different CNAMEs when PeerConnections are created.
// The CNAMEs are expected to be generated randomly. It is possible
// that the test fails, though the possibility is very low.
TEST_P(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
  std::unique_ptr<SessionDescriptionInterface> offer1 =
      CreateOfferWithOneAudioTrack();
  std::unique_ptr<SessionDescriptionInterface> offer2 =
      CreateOfferWithOneAudioTrack();
  EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
            GetFirstAudioStreamCname(offer2.get()));
}

TEST_P(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
  std::unique_ptr<SessionDescriptionInterface> answer1 =
      CreateAnswerWithOneAudioTrack();
  std::unique_ptr<SessionDescriptionInterface> answer2 =
      CreateAnswerWithOneAudioTrack();
  EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
            GetFirstAudioStreamCname(answer2.get()));
}

TEST_P(PeerConnectionInterfaceTest,
       CreatePeerConnectionWithDifferentConfigurations) {
  CreatePeerConnectionWithDifferentConfigurations();
}

TEST_P(PeerConnectionInterfaceTest,
       CreatePeerConnectionWithDifferentIceTransportsTypes) {
  CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
  network_thread_->BlockingCall(
      [&] { EXPECT_EQ(CF_NONE, port_allocator_->candidate_filter()); });
  CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
  network_thread_->BlockingCall(
      [&] { EXPECT_EQ(CF_RELAY, port_allocator_->candidate_filter()); });
  CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
  network_thread_->BlockingCall([&] {
    EXPECT_EQ(CF_ALL & ~CF_HOST, port_allocator_->candidate_filter());
  });
  CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
  network_thread_->BlockingCall(
      [&] { EXPECT_EQ(CF_ALL, port_allocator_->candidate_filter()); });
}

// Test that when a PeerConnection is created with a nonzero candidate pool
// size, the pooled PortAllocatorSession is created with all the attributes
// in the RTCConfiguration.
TEST_P(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  PeerConnectionInterface::IceServer server;
  server.uri = kStunAddressOnly;
  config.servers.push_back(server);
  config.type = PeerConnectionInterface::kRelay;
  config.tcp_candidate_policy =
      PeerConnectionInterface::kTcpCandidatePolicyDisabled;
  config.candidate_network_policy =
      PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
  config.ice_candidate_pool_size = 1;
  CreatePeerConnection(config);

  network_thread_->BlockingCall([&] {
    const FakePortAllocatorSession* session =
        static_cast<const FakePortAllocatorSession*>(
            port_allocator_->GetPooledSession());
    ASSERT_NE(nullptr, session);
    EXPECT_EQ(1UL, session->stun_servers().size());
    EXPECT_LT(0U, session->flags() & PORTALLOCATOR_DISABLE_TCP);
    EXPECT_LT(0U, session->flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
  });
}

// Test that network-related RTCConfiguration members are applied to the
// PortAllocator when CreatePeerConnection is called. Specifically:
// - disable_ipv6_on_wifi
// - max_ipv6_networks
// - tcp_candidate_policy
// - candidate_network_policy
// - prune_turn_ports
//
// Note that the candidate filter (RTCConfiguration::type) is already tested
// above.
TEST_P(PeerConnectionInterfaceTest,
       CreatePeerConnectionAppliesNetworkConfigToPortAllocator) {
  // Create fake port allocator.
  // Create fake port allocator on the network thread.
  std::unique_ptr<FakePortAllocator> port_allocator;
  network_thread_->BlockingCall([&] {
    port_allocator = std::make_unique<FakePortAllocator>(
        CreateTestEnvironment(), network_thread_->socketserver());
  });
  // We need to keep a raw pointer to check flags later, but we need to
  // accessing it on the network thread or be careful. FakePortAllocator methods
  // might be thread-safe or check threads. `flags()` is on BasicPortAllocator,
  // which checks thread_checker_. So we must access it on network thread.
  FakePortAllocator* raw_port_allocator = port_allocator.get();

  // Create RTCConfiguration with some network-related fields relevant to
  // PortAllocator populated.
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.disable_ipv6_on_wifi = true;
  config.max_ipv6_networks = 10;
  config.tcp_candidate_policy =
      PeerConnectionInterface::kTcpCandidatePolicyDisabled;
  config.candidate_network_policy =
      PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
  config.prune_turn_ports = true;

  // Create the PC factory and PC with the above config.
  PeerConnectionDependencies pc_dependencies(&observer_);
  pc_dependencies.allocator = std::move(port_allocator);
  auto result = pc_factory_->CreatePeerConnectionOrError(
      config, std::move(pc_dependencies));
  EXPECT_TRUE(result.ok());
  observer_.SetPeerConnectionInterface(result.value().get());

  // Now validate that the config fields set above were applied to the
  // PortAllocator, as flags or otherwise.
  network_thread_->BlockingCall([&] {
    EXPECT_FALSE(raw_port_allocator->flags() &
                 PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
    EXPECT_EQ(10, raw_port_allocator->max_ipv6_networks());
    EXPECT_TRUE(raw_port_allocator->flags() & PORTALLOCATOR_DISABLE_TCP);
    EXPECT_TRUE(raw_port_allocator->flags() &
                PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
    EXPECT_EQ(PRUNE_BASED_ON_PRIORITY,
              raw_port_allocator->turn_port_prune_policy());
  });
}

// Check that GetConfiguration returns the configuration the PeerConnection was
// constructed with, before SetConfiguration is called.
TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.type = PeerConnectionInterface::kRelay;
  CreatePeerConnection(config);

  PeerConnectionInterface::RTCConfiguration returned_config =
      pc_->GetConfiguration();
  EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
}

// Check that GetConfiguration returns the last configuration passed into
// SetConfiguration.
TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
  PeerConnectionInterface::RTCConfiguration starting_config;
  starting_config.sdp_semantics = sdp_semantics_;
  starting_config.bundle_policy = PeerConnection::kBundlePolicyMaxBundle;
  CreatePeerConnection(starting_config);

  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.type = PeerConnectionInterface::kRelay;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  PeerConnectionInterface::RTCConfiguration returned_config =
      pc_->GetConfiguration();
  EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
}

TEST_P(PeerConnectionInterfaceTest, SetConfigurationFailsAfterClose) {
  CreatePeerConnection();

  pc_->Close();

  EXPECT_FALSE(
      pc_->SetConfiguration(PeerConnectionInterface::RTCConfiguration()).ok());
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
TEST_F(PeerConnectionInterfaceTestPlanB, AddStreams) {
  CreatePeerConnectionWithoutDtls();
  AddVideoStream(kStreamId1);
  AddAudioStream(kStreamId2);
  ASSERT_EQ(2u, pc_->local_streams()->count());

  // Test we can add multiple local streams to one peerconnection.
  scoped_refptr<MediaStreamInterface> stream(
      pc_factory_->CreateLocalMediaStream(kStreamId3));
  scoped_refptr<AudioTrackInterface> audio_track(pc_factory_->CreateAudioTrack(
      kStreamId3, static_cast<AudioSourceInterface*>(nullptr)));
  stream->AddTrack(audio_track);
  EXPECT_TRUE(pc_->AddStream(stream.get()));
  EXPECT_EQ(3u, pc_->local_streams()->count());

  // Remove the third stream.
  pc_->RemoveStream(pc_->local_streams()->at(2));
  EXPECT_EQ(2u, pc_->local_streams()->count());

  // Remove the second stream.
  pc_->RemoveStream(pc_->local_streams()->at(1));
  EXPECT_EQ(1u, pc_->local_streams()->count());

  // Remove the first stream.
  pc_->RemoveStream(pc_->local_streams()->at(0));
  EXPECT_EQ(0u, pc_->local_streams()->count());
}

// Test that the created offer includes streams we added.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, AddedStreamsPresentInOffer) {
  CreatePeerConnectionWithoutDtls();
  AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const AudioContentDescription* audio_desc =
      GetFirstAudioContentDescription(offer->description());
  EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));

  const VideoContentDescription* video_desc =
      GetFirstVideoContentDescription(offer->description());
  EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));

  // Add another stream and ensure the offer includes both the old and new
  // streams.
  AddAudioVideoStream(kStreamId2, "audio_track2", "video_track2");
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  audio_desc = GetFirstAudioContentDescription(offer->description());
  EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));
  EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId2, "audio_track2"));

  video_desc = GetFirstVideoContentDescription(offer->description());
  EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));
  EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId2, "video_track2"));
}

// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, RemoveStream) {
  CreatePeerConnectionWithoutDtls();
  AddVideoStream(kStreamId1);
  ASSERT_EQ(1u, pc_->local_streams()->count());
  pc_->RemoveStream(pc_->local_streams()->at(0));
  EXPECT_EQ(0u, pc_->local_streams()->count());
}

// Test for AddTrack and RemoveTrack methods.
// Tests that the created offer includes tracks we added,
// and that the RtpSenders are created correctly.
// Also tests that RemoveTrack removes the tracks from subsequent offers.
// Only tested with Plan B since Unified Plan is covered in more detail by tests
// in peerconnection_jsep_unittests.cc
TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackRemoveTrack) {
  CreatePeerConnectionWithoutDtls();
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  auto audio_sender = pc_->AddTrack(audio_track, {kStreamId1}).MoveValue();
  auto video_sender = pc_->AddTrack(video_track, {kStreamId1}).MoveValue();
  EXPECT_EQ(1UL, audio_sender->stream_ids().size());
  EXPECT_EQ(kStreamId1, audio_sender->stream_ids()[0]);
  EXPECT_EQ("audio_track", audio_sender->id());
  EXPECT_EQ(audio_track, audio_sender->track());
  EXPECT_EQ(1UL, video_sender->stream_ids().size());
  EXPECT_EQ(kStreamId1, video_sender->stream_ids()[0]);
  EXPECT_EQ("video_track", video_sender->id());
  EXPECT_EQ(video_track, video_sender->track());

  // Now create an offer and check for the senders.
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const ContentInfo* audio_content = GetFirstAudioContent(offer->description());
  EXPECT_TRUE(ContainsTrack(audio_content->media_description()->streams(),
                            kStreamId1, "audio_track"));

  const ContentInfo* video_content = GetFirstVideoContent(offer->description());
  EXPECT_TRUE(ContainsTrack(video_content->media_description()->streams(),
                            kStreamId1, "video_track"));

  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  // Now try removing the tracks.
  EXPECT_TRUE(pc_->RemoveTrackOrError(audio_sender).ok());
  EXPECT_TRUE(pc_->RemoveTrackOrError(video_sender).ok());

  // Create a new offer and ensure it doesn't contain the removed senders.
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  audio_content = GetFirstAudioContent(offer->description());
  EXPECT_FALSE(ContainsTrack(audio_content->media_description()->streams(),
                             kStreamId1, "audio_track"));

  video_content = GetFirstVideoContent(offer->description());
  EXPECT_FALSE(ContainsTrack(video_content->media_description()->streams(),
                             kStreamId1, "video_track"));

  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  // Calling RemoveTrack on a sender no longer attached to a PeerConnection
  // should return false.
  EXPECT_FALSE(pc_->RemoveTrackOrError(audio_sender).ok());
  EXPECT_FALSE(pc_->RemoveTrackOrError(video_sender).ok());
}

// Test for AddTrack with init_send_encoding.
TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackWithSendEncodings) {
  CreatePeerConnectionWithoutDtls();
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  RtpEncodingParameters audio_encodings;
  audio_encodings.active = false;
  auto audio_sender =
      pc_->AddTrack(audio_track, {kStreamId1}, {audio_encodings}).MoveValue();
  RtpEncodingParameters video_encodings;
  video_encodings.active = true;
  auto video_sender =
      pc_->AddTrack(video_track, {kStreamId1}, {video_encodings}).MoveValue();
  EXPECT_EQ(1UL, audio_sender->stream_ids().size());
  EXPECT_EQ(kStreamId1, audio_sender->stream_ids()[0]);
  EXPECT_EQ("audio_track", audio_sender->id());
  EXPECT_EQ(audio_track, audio_sender->track());
  EXPECT_EQ(1UL, video_sender->stream_ids().size());
  EXPECT_EQ(kStreamId1, video_sender->stream_ids()[0]);
  EXPECT_EQ("video_track", video_sender->id());
  EXPECT_EQ(video_track, video_sender->track());

  // Now create an offer and check for the senders.
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const ContentInfo* audio_content = GetFirstAudioContent(offer->description());
  EXPECT_TRUE(ContainsTrack(audio_content->media_description()->streams(),
                            kStreamId1, "audio_track"));

  const ContentInfo* video_content = GetFirstVideoContent(offer->description());
  EXPECT_TRUE(ContainsTrack(video_content->media_description()->streams(),
                            kStreamId1, "video_track"));

  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  // Check the encodings.
  ASSERT_THAT(audio_sender->GetParameters().encodings, SizeIs(1));
  EXPECT_THAT(audio_sender->GetParameters().encodings[0].active, Eq(false));
  ASSERT_THAT(video_sender->GetParameters().encodings, SizeIs(1));
  EXPECT_THAT(video_sender->GetParameters().encodings[0].active, Eq(true));

  // Now try removing the tracks.
  EXPECT_TRUE(pc_->RemoveTrackOrError(audio_sender).ok());
  EXPECT_TRUE(pc_->RemoveTrackOrError(video_sender).ok());
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test creating senders without a stream specified,
// expecting a random stream ID to be generated.
TEST_P(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
  CreatePeerConnectionWithoutDtls();
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  auto audio_sender =
      pc_->AddTrack(audio_track, std::vector<std::string>()).MoveValue();
  auto video_sender =
      pc_->AddTrack(video_track, std::vector<std::string>()).MoveValue();
  EXPECT_EQ("audio_track", audio_sender->id());
  EXPECT_EQ(audio_track, audio_sender->track());
  EXPECT_EQ("video_track", video_sender->id());
  EXPECT_EQ(video_track, video_sender->track());
  if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
    // If the ID is truly a random GUID, it should be infinitely unlikely they
    // will be the same.
    EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
  } else {
    // We allows creating tracks without stream ids under Unified Plan
    // semantics.
    EXPECT_EQ(0u, video_sender->stream_ids().size());
    EXPECT_EQ(0u, audio_sender->stream_ids().size());
  }
}

// Test that we can call GetStats() after AddTrack but before connecting
// the PeerConnection to a peer.
TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) {
  CreatePeerConnection();
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
  auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
  EXPECT_TRUE(DoGetRTCStats());
}

TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) {
  CreatePeerConnection();
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
  ASSERT_TRUE(audio_sender.ok());
  auto* audio_sender_proxy =
      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
          audio_sender.value().get());
  EXPECT_NE(0, audio_sender_proxy->internal()->AttachmentId());

  auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
  ASSERT_TRUE(video_sender.ok());
  auto* video_sender_proxy =
      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
          video_sender.value().get());
  EXPECT_NE(0, video_sender_proxy->internal()->AttachmentId());
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, AttachmentIdIsSetOnAddStream) {
  CreatePeerConnection();
  AddVideoStream(kStreamId1);
  auto senders = pc_->GetSenders();
  ASSERT_EQ(1u, senders.size());
  auto* sender_proxy =
      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
          senders[0].get());
  EXPECT_NE(0, sender_proxy->internal()->AttachmentId());
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

TEST_P(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
  InitiateCall();
  WaitAndVerifyOnAddStream(kStreamId1, 2);
  VerifyRemoteRtpHeaderExtensions();
}

TEST_P(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
  CreatePeerConnectionWithoutDtls();
  AddVideoTrack(kVideoTracks[0], {kStreamId1});
  CreateOfferAsLocalDescription();
  std::string offer;
  EXPECT_TRUE(pc_->local_description()->ToString(&offer));
  CreatePrAnswerAndAnswerAsRemoteDescription(offer);
  WaitAndVerifyOnAddStream(kStreamId1, 1);
}

TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
  CreatePeerConnectionWithoutDtls();
  AddVideoTrack(kVideoTracks[0], {kStreamId1});

  CreateOfferAsRemoteDescription();
  CreateAnswerAsLocalDescription();

  WaitAndVerifyOnAddStream(kStreamId1, 1);
}

TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
  CreatePeerConnectionWithoutDtls();
  AddVideoTrack(kVideoTracks[0], {kStreamId1});

  CreateOfferAsRemoteDescription();
  CreatePrAnswerAsLocalDescription();
  CreateAnswerAsLocalDescription();

  WaitAndVerifyOnAddStream(kStreamId1, 1);
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, Renegotiate) {
  InitiateCall();
  ASSERT_EQ(1u, pc_->remote_streams()->count());
  pc_->RemoveStream(pc_->local_streams()->at(0));
  CreateOfferReceiveAnswer();
  EXPECT_EQ(0u, pc_->remote_streams()->count());
  AddVideoStream(kStreamId1);
  CreateOfferReceiveAnswer();
}

// Tests that after negotiating an audio only call, the respondent can perform a
// renegotiation that removes the audio stream.
TEST_F(PeerConnectionInterfaceTestPlanB, RenegotiateAudioOnly) {
  CreatePeerConnectionWithoutDtls();
  AddAudioStream(kStreamId1);
  CreateOfferAsRemoteDescription();
  CreateAnswerAsLocalDescription();

  ASSERT_EQ(1u, pc_->remote_streams()->count());
  pc_->RemoveStream(pc_->local_streams()->at(0));
  CreateOfferReceiveAnswer();
  EXPECT_EQ(0u, pc_->remote_streams()->count());
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test that candidates are generated and that we can parse our own candidates.
TEST_P(PeerConnectionInterfaceTest, IceCandidates) {
  CreatePeerConnectionWithoutDtls();

  EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate()));
  // SetRemoteDescription takes ownership of offer.
  std::unique_ptr<SessionDescriptionInterface> offer;
  AddVideoTrack(kVideoTracks[0]);
  EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));

  // SetLocalDescription takes ownership of answer.
  std::unique_ptr<SessionDescriptionInterface> answer;
  EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));

  EXPECT_THAT(WaitUntil([&] { return observer_.last_candidate(); },
                        ::testing::Ne(nullptr),
                        {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return observer_.ice_gathering_complete_; },
                        IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());

  EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate()));
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Test that CreateOffer and CreateAnswer will fail if the track labels are
// not unique.
TEST_F(PeerConnectionInterfaceTestPlanB, CreateOfferAnswerWithInvalidStream) {
  CreatePeerConnectionWithoutDtls();
  // Create a regular offer for the CreateAnswer test later.
  std::unique_ptr<SessionDescriptionInterface> offer;
  EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(offer);
  offer.reset();

  // Create a local stream with audio&video tracks having same label.
  AddAudioTrack("track_label", {kStreamId1});
  AddVideoTrack("track_label", {kStreamId1});

  // Test CreateOffer
  EXPECT_FALSE(DoCreateOffer(&offer, nullptr));

  // Test CreateAnswer
  std::unique_ptr<SessionDescriptionInterface> answer;
  EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test that we will get different SSRCs for each tracks in the offer and answer
// we created.
TEST_P(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
  CreatePeerConnectionWithoutDtls();
  // Create a local stream with audio&video tracks having different labels.
  AddAudioTrack(kAudioTracks[0], {kStreamId1});
  AddVideoTrack(kVideoTracks[0], {kStreamId1});

  // Test CreateOffer
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  int audio_ssrc = 0;
  int video_ssrc = 0;
  EXPECT_TRUE(
      GetFirstSsrc(GetFirstAudioContent(offer->description()), &audio_ssrc));
  EXPECT_TRUE(
      GetFirstSsrc(GetFirstVideoContent(offer->description()), &video_ssrc));
  EXPECT_NE(audio_ssrc, video_ssrc);

  // Test CreateAnswer
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
  audio_ssrc = 0;
  video_ssrc = 0;
  EXPECT_TRUE(
      GetFirstSsrc(GetFirstAudioContent(answer->description()), &audio_ssrc));
  EXPECT_TRUE(
      GetFirstSsrc(GetFirstVideoContent(answer->description()), &video_ssrc));
  EXPECT_NE(audio_ssrc, video_ssrc);
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Test that it's possible to call AddTrack on a MediaStream after adding
// the stream to a PeerConnection.
// TODO(deadbeef): Remove this test once this behavior is no longer supported.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackAfterAddStream) {
  CreatePeerConnectionWithoutDtls();
  // Create audio stream and add to PeerConnection.
  AddAudioStream(kStreamId1);
  MediaStreamInterface* stream = pc_->local_streams()->at(0);

  // Add video track to the audio-only stream.
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_label"));
  stream->AddTrack(video_track);

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const MediaContentDescription* video_desc =
      GetFirstVideoContentDescription(offer->description());
  EXPECT_TRUE(video_desc != nullptr);
}

// Test that it's possible to call RemoveTrack on a MediaStream after adding
// the stream to a PeerConnection.
// TODO(deadbeef): Remove this test once this behavior is no longer supported.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackAfterAddStream) {
  CreatePeerConnectionWithoutDtls();
  // Create audio/video stream and add to PeerConnection.
  AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
  MediaStreamInterface* stream = pc_->local_streams()->at(0);

  // Remove the video track.
  stream->RemoveTrack(stream->GetVideoTracks()[0]);

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const MediaContentDescription* video_desc =
      GetFirstVideoContentDescription(offer->description());
  EXPECT_TRUE(video_desc == nullptr);
}

// Test creating a sender with a stream ID, and ensure the ID is populated
// in the offer.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, CreateSenderWithStream) {
  CreatePeerConnectionWithoutDtls();
  pc_->CreateSender("video", kStreamId1);

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));

  const MediaContentDescription* video_desc =
      GetFirstVideoContentDescription(offer->description());
  ASSERT_TRUE(video_desc != nullptr);
  ASSERT_EQ(1u, video_desc->streams().size());
  EXPECT_EQ(kStreamId1, video_desc->streams()[0].first_stream_id());
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test that we can specify a certain track that we want statistics about.
TEST_P(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
  InitiateCall();
  ASSERT_LT(0u, pc_->GetSenders().size());
  ASSERT_LT(0u, pc_->GetReceivers().size());
  scoped_refptr<MediaStreamTrackInterface> remote_audio =
      pc_->GetReceivers()[0]->track();
  EXPECT_TRUE(DoGetRTCStats());

  // Remove the stream. Since we are sending to our selves the local
  // and the remote stream is the same.
  pc_->RemoveTrackOrError(pc_->GetSenders()[0]);
  // Do a re-negotiation.
  CreateOfferReceiveAnswer();

  // Test that we still can get statistics for the old track. Even if it is not
  // sent any longer.
  EXPECT_TRUE(DoGetRTCStats());
}

// Test that we can get stats on a video track.
TEST_P(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
  InitiateCall();
  auto video_receiver = GetFirstReceiverOfType(MediaType::VIDEO);
  ASSERT_TRUE(video_receiver);
  EXPECT_TRUE(DoGetRTCStats());
}

// Test that we don't get statistics for an invalid track.
TEST_P(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
  InitiateCall();
  scoped_refptr<AudioTrackInterface> unknown_audio_track(
      pc_factory_->CreateAudioTrack("unknown track", nullptr));
  EXPECT_FALSE(DoGetStats(unknown_audio_track.get()));
}

TEST_P(PeerConnectionInterfaceTest, GetRTCStatsBeforeAndAfterCalling) {
  CreatePeerConnectionWithoutDtls();
  EXPECT_TRUE(DoGetRTCStats());
  // Clearing stats cache is needed now, but should be temporary.
  // https://bugs.chromium.org/p/webrtc/issues/detail?id=8693
  pc_->ClearStatsCache();
  AddAudioTrack(kAudioTracks[0], {kStreamId1});
  AddVideoTrack(kVideoTracks[0], {kStreamId1});
  EXPECT_TRUE(DoGetRTCStats());
  pc_->ClearStatsCache();
  CreateOfferReceiveAnswer();
  EXPECT_TRUE(DoGetRTCStats());
}

// This tests that a SCTP data channel is returned using different
// DataChannelInit configurations.
TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  DataChannelInit config;
  auto channel = pc_->CreateDataChannelOrError("1", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_TRUE(channel.value()->reliable());
  EXPECT_TRUE(observer_.renegotiation_needed_);
  observer_.renegotiation_needed_ = false;

  config.ordered = false;
  channel = pc_->CreateDataChannelOrError("2", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_TRUE(channel.value()->reliable());
  EXPECT_FALSE(observer_.renegotiation_needed_);

  config.ordered = true;
  config.maxRetransmits = 0;
  channel = pc_->CreateDataChannelOrError("3", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_FALSE(channel.value()->reliable());
  EXPECT_FALSE(observer_.renegotiation_needed_);

  config.maxRetransmits = std::nullopt;
  config.maxRetransmitTime = 0;
  channel = pc_->CreateDataChannelOrError("4", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_FALSE(channel.value()->reliable());
  EXPECT_FALSE(observer_.renegotiation_needed_);
}

TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWhenClosed) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);
  pc_->Close();
  DataChannelInit config;
  auto ret = pc_->CreateDataChannelOrError("1", &config);
  ASSERT_FALSE(ret.ok());
  EXPECT_EQ(ret.error().type(), RTCErrorType::INVALID_STATE);
}

// For backwards compatibility, we want people who "unset" maxRetransmits
// and maxRetransmitTime by setting them to -1 to get what they want.
TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWithMinusOne) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  DataChannelInit config;
  config.maxRetransmitTime = -1;
  config.maxRetransmits = -1;
  auto channel = pc_->CreateDataChannelOrError("1", &config);
  EXPECT_TRUE(channel.ok());
}

// This tests that no data channel is returned if both maxRetransmits and
// maxRetransmitTime are set for SCTP data channels.
TEST_P(PeerConnectionInterfaceTest,
       CreateSctpDataChannelShouldFailForInvalidConfig) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  std::string label = "test";
  DataChannelInit config;
  config.maxRetransmits = 0;
  config.maxRetransmitTime = 0;

  auto channel = pc_->CreateDataChannelOrError(label, &config);
  EXPECT_FALSE(channel.ok());
}

// The test verifies that creating a SCTP data channel with an id already in use
// or out of range should fail.
TEST_P(PeerConnectionInterfaceTest,
       CreateSctpDataChannelWithInvalidIdShouldFail) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  DataChannelInit config;

  config.id = 1;
  config.negotiated = true;
  auto channel = pc_->CreateDataChannelOrError("1", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_EQ(1, channel.value()->id());

  channel = pc_->CreateDataChannelOrError("x", &config);
  EXPECT_FALSE(channel.ok());

  config.id = kMaxSctpSid;
  config.negotiated = true;
  channel = pc_->CreateDataChannelOrError("max", &config);
  EXPECT_TRUE(channel.ok());
  EXPECT_EQ(config.id, channel.value()->id());

  config.id = kMaxSctpSid + 1;
  config.negotiated = true;
  channel = pc_->CreateDataChannelOrError("x", &config);
  EXPECT_FALSE(channel.ok());
}

// Verifies that duplicated label is allowed for SCTP data channel.
TEST_P(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  std::string label = "test";
  auto channel = pc_->CreateDataChannelOrError(label, nullptr);
  EXPECT_TRUE(channel.ok());

  auto dup_channel = pc_->CreateDataChannelOrError(label, nullptr);
  EXPECT_TRUE(dup_channel.ok());
}

#ifdef WEBRTC_HAVE_SCTP
// This tests that SCTP data channels can be rejected in an answer.
TEST_P(PeerConnectionInterfaceTest, TestRejectSctpDataChannelInAnswer)
#else
TEST_P(PeerConnectionInterfaceTest, DISABLED_TestRejectSctpDataChannelInAnswer)
#endif
{
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);

  auto offer_channel = pc_->CreateDataChannelOrError("offer_channel", nullptr);

  CreateOfferAsLocalDescription();

  // Create an answer where the m-line for data channels are rejected.
  std::string sdp;
  EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
  std::unique_ptr<SessionDescriptionInterface> answer(
      CreateSessionDescription(SdpType::kAnswer, sdp));
  ASSERT_THAT(answer, NotNull());
  ContentInfo* data_info = GetFirstDataContent(answer->description());
  data_info->rejected = true;

  DoSetRemoteDescription(std::move(answer));
  EXPECT_EQ(DataChannelInterface::kClosed, offer_channel.value()->state());
}

// Test that we can create a session description from an SDP string from
// FireFox, use it as a remote session description, generate an answer and use
// the answer as a local description.
TEST_P(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);
  AddAudioTrack("audio_label");
  AddVideoTrack("video_label");
  std::unique_ptr<SessionDescriptionInterface> desc(
      CreateSessionDescription(SdpType::kOffer, kFireFoxSdpOffer, nullptr));
  EXPECT_TRUE(DoSetSessionDescription(std::move(desc), false));
  CreateAnswerAsLocalDescription();
  ASSERT_TRUE(pc_->local_description() != nullptr);
  ASSERT_TRUE(pc_->remote_description() != nullptr);

  const ContentInfo* content =
      GetFirstAudioContent(pc_->local_description()->description());
  ASSERT_TRUE(content != nullptr);
  EXPECT_FALSE(content->rejected);

  content = GetFirstVideoContent(pc_->local_description()->description());
  ASSERT_TRUE(content != nullptr);
  EXPECT_FALSE(content->rejected);
#ifdef WEBRTC_HAVE_SCTP
  content = GetFirstDataContent(pc_->local_description()->description());
  ASSERT_TRUE(content != nullptr);
  EXPECT_FALSE(content->rejected);
#endif
}

// Test that we can create an audio only offer and receive an answer with a
// limited set of audio codecs and receive an updated offer with more audio
// codecs, where the added codecs are not supported.
TEST_P(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
  CreatePeerConnectionWithoutDtls();
  AddAudioTrack("audio_label");
  CreateOfferAsLocalDescription();

  const char* answer_sdp = (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED
                                ? kAudioSdpPlanB
                                : kAudioSdpUnifiedPlan);
  std::unique_ptr<SessionDescriptionInterface> answer(
      CreateSessionDescription(SdpType::kAnswer, answer_sdp, nullptr));
  EXPECT_TRUE(DoSetSessionDescription(std::move(answer), false));

  const char* reoffer_sdp = (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED
                                 ? kAudioSdpWithUnsupportedCodecsPlanB
                                 : kAudioSdpWithUnsupportedCodecsUnifiedPlan);
  std::unique_ptr<SessionDescriptionInterface> updated_offer(
      CreateSessionDescription(SdpType::kOffer, reoffer_sdp, nullptr));
  EXPECT_TRUE(DoSetSessionDescription(std::move(updated_offer), false));
  CreateAnswerAsLocalDescription();
}

// Test that if we're receiving (but not sending) a track, subsequent offers
// will have m-lines with a=recvonly.
TEST_P(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());
  CreateAnswerAsLocalDescription();

  // At this point we should be receiving stream 1, but not sending anything.
  // A new offer should be recvonly.
  std::unique_ptr<SessionDescriptionInterface> offer;
  DoCreateOffer(&offer, nullptr);

  const ContentInfo* video_content = GetFirstVideoContent(offer->description());
  ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
            video_content->media_description()->direction());

  const ContentInfo* audio_content = GetFirstAudioContent(offer->description());
  ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
            audio_content->media_description()->direction());
}

// Test that if we're receiving (but not sending) a track, and the
// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
// false, the generated m-lines will be a=inactive.
TEST_P(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
  RTCConfiguration rtc_config;
  CreatePeerConnection(rtc_config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());
  CreateAnswerAsLocalDescription();

  // At this point we should be receiving stream 1, but not sending anything.
  // A new offer would be recvonly, but we'll set the "no receive" constraints
  // to make it inactive.
  std::unique_ptr<SessionDescriptionInterface> offer;
  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 0;
  options.offer_to_receive_video = 0;
  DoCreateOffer(&offer, &options);

  const ContentInfo* video_content = GetFirstVideoContent(offer->description());
  ASSERT_EQ(RtpTransceiverDirection::kInactive,
            video_content->media_description()->direction());

  const ContentInfo* audio_content = GetFirstAudioContent(offer->description());
  ASSERT_EQ(RtpTransceiverDirection::kInactive,
            audio_content->media_description()->direction());
}

// Test that we can use SetConfiguration to change the ICE servers of the
// PortAllocator.
TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
  CreatePeerConnection();

  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  PeerConnectionInterface::IceServer server;
  server.uri = "stun:test_hostname";
  config.servers.push_back(server);
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  network_thread_->BlockingCall([&] {
    EXPECT_EQ(1u, port_allocator_->stun_servers().size());
    EXPECT_EQ("test_hostname",
              port_allocator_->stun_servers().begin()->hostname());
  });
}

TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
  CreatePeerConnection();
  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.type = PeerConnectionInterface::kRelay;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  network_thread_->BlockingCall(
      [&] { EXPECT_EQ(CF_RELAY, port_allocator_->candidate_filter()); });
}

TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
  PeerConnectionInterface::RTCConfiguration config;
  config.prune_turn_ports = false;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  network_thread_->BlockingCall(
      [&] { EXPECT_EQ(NO_PRUNE, port_allocator_->turn_port_prune_policy()); });

  config.prune_turn_ports = true;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  network_thread_->BlockingCall([&] {
    EXPECT_EQ(PRUNE_BASED_ON_PRIORITY,
              port_allocator_->turn_port_prune_policy());
  });
}

// Test that the ice check interval can be changed. This does not verify that
// the setting makes it all the way to P2PTransportChannel, as that would
// require a very complex set of mocks.
TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
  PeerConnectionInterface::RTCConfiguration config;
  config.ice_check_min_interval = std::nullopt;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  config.ice_check_min_interval = 100;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  config = pc_->GetConfiguration();
  EXPECT_EQ(config.ice_check_min_interval, 100);
}

TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationChangesSurfaceIceCandidatesOnIceTransportTypeChanged) {
  PeerConnectionInterface::RTCConfiguration config;
  config.surface_ice_candidates_on_ice_transport_type_changed = false;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  EXPECT_FALSE(config.surface_ice_candidates_on_ice_transport_type_changed);

  config.surface_ice_candidates_on_ice_transport_type_changed = true;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  config = pc_->GetConfiguration();
  EXPECT_TRUE(config.surface_ice_candidates_on_ice_transport_type_changed);
}

// Test that when SetConfiguration changes both the pool size and other
// attributes, the pooled session is created with the updated attributes.
TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationCreatesPooledSessionCorrectly) {
  CreatePeerConnection();
  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.ice_candidate_pool_size = 1;
  PeerConnectionInterface::IceServer server;
  server.uri = kStunAddressOnly;
  config.servers.push_back(server);
  config.type = PeerConnectionInterface::kRelay;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  network_thread_->BlockingCall([&] {
    const FakePortAllocatorSession* session =
        static_cast<const FakePortAllocatorSession*>(
            port_allocator_->GetPooledSession());
    ASSERT_NE(nullptr, session);
    EXPECT_EQ(1UL, session->stun_servers().size());
  });
}

// Test that after SetLocalDescription, changing the pool size is not allowed,
// and an invalid modification error is returned.
TEST_P(PeerConnectionInterfaceTest,
       CantChangePoolSizeAfterSetLocalDescription) {
  CreatePeerConnection();
  // Start by setting a size of 1.
  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.ice_candidate_pool_size = 1;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  // Set remote offer; can still change pool size at this point.
  CreateOfferAsRemoteDescription();
  config.ice_candidate_pool_size = 2;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  // Set local answer; now it's too late.
  CreateAnswerAsLocalDescription();
  config.ice_candidate_pool_size = 3;
  RTCError error = pc_->SetConfiguration(config);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
}

// Test that after setting an answer, extra pooled sessions are discarded. The
// ICE candidate pool is only intended to be used for the first offer/answer.
TEST_P(PeerConnectionInterfaceTest,
       ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
  CreatePeerConnection();

  // Set a larger-than-necessary size.
  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.ice_candidate_pool_size = 4;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  // Do offer/answer.
  CreateOfferAsRemoteDescription();
  CreateAnswerAsLocalDescription();

  // Expect no pooled sessions to be left.
  network_thread_->BlockingCall([&] {
    const PortAllocatorSession* session = port_allocator_->GetPooledSession();
    EXPECT_EQ(nullptr, session);
  });
}

// After Close is called, pooled candidates should be discarded so as to not
// waste network resources.
TEST_P(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
  CreatePeerConnection();

  bool candidate_pool_discarded = false;
  network_thread_->BlockingCall([&] {
    port_allocator_->SetOnDiscardCandidatePool(
        [&]() { candidate_pool_discarded = true; });
  });

  PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
  config.ice_candidate_pool_size = 3;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  pc_->Close();

  EXPECT_TRUE(candidate_pool_discarded);
}

// Test that SetConfiguration returns an invalid modification error if
// modifying a field in the configuration that isn't allowed to be modified.
TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationReturnsInvalidModificationError) {
  PeerConnectionInterface::RTCConfiguration config;
  config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
  config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
  config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
  CreatePeerConnection(config);

  PeerConnectionInterface::RTCConfiguration modified_config =
      pc_->GetConfiguration();
  modified_config.bundle_policy =
      PeerConnectionInterface::kBundlePolicyMaxBundle;
  RTCError error = pc_->SetConfiguration(modified_config);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());

  modified_config = pc_->GetConfiguration();
  modified_config.rtcp_mux_policy =
      PeerConnectionInterface::kRtcpMuxPolicyRequire;
  error = pc_->SetConfiguration(modified_config);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());

  modified_config = pc_->GetConfiguration();
  modified_config.continual_gathering_policy =
      PeerConnectionInterface::GATHER_CONTINUALLY;
  error = pc_->SetConfiguration(modified_config);
  EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
}

// Test that SetConfiguration returns a range error if the candidate pool size
// is negative or larger than allowed by the spec.
TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
  PeerConnectionInterface::RTCConfiguration config;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();

  config.ice_candidate_pool_size = -1;
  RTCError error = pc_->SetConfiguration(config);
  EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());

  config.ice_candidate_pool_size = INT_MAX;
  error = pc_->SetConfiguration(config);
  EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
}

// Test that SetConfiguration returns a syntax error if parsing an ICE server
// URL failed.
TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
  PeerConnectionInterface::RTCConfiguration config;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();

  PeerConnectionInterface::IceServer bad_server;
  bad_server.uri = "stunn:www.example.com";
  config.servers.push_back(bad_server);
  RTCError error = pc_->SetConfiguration(config);
  EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
}

// Test that SetConfiguration returns an invalid parameter error if a TURN
// IceServer is missing a username or password.
TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
  PeerConnectionInterface::RTCConfiguration config;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();

  PeerConnectionInterface::IceServer bad_server;
  bad_server.uri = "turn:www.example.com";
  // Missing password.
  bad_server.username = "foo";
  config.servers.push_back(bad_server);
  RTCError error;
  EXPECT_EQ(pc_->SetConfiguration(config).type(),
            RTCErrorType::INVALID_PARAMETER);
}

TEST_P(PeerConnectionInterfaceTest, UnmodifiedSetConfigurationSucceeds) {
  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;

    CreatePeerConnection(config);

    EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  }

  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  }
}

TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationSucceedsWithMatchingCryptoOptions) {
  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;

    CreatePeerConnection(config);

    config.crypto_options = CryptoOptions();
    EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  }

  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    config.crypto_options = CryptoOptions();
    EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  }

  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;
    CryptoOptions options;
    options.ephemeral_key_exchange_cipher_groups.SetEnabled({
        webrtc::CryptoOptions::EphemeralKeyExchangeCipherGroups::
            kX25519_MLKEM768,
    });
    config.crypto_options = options;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  }
}

TEST_P(PeerConnectionInterfaceTest,
       SetConfigurationFailsWithMismatchingCryptoOptions) {
  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    CryptoOptions options;
    options.ephemeral_key_exchange_cipher_groups.SetEnabled({
        webrtc::CryptoOptions::EphemeralKeyExchangeCipherGroups::
            kX25519_MLKEM768,
    });
    config.crypto_options = options;

    RTCError error = pc_->SetConfiguration(config);
    EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
  }

  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;
    CryptoOptions options;
    options.ephemeral_key_exchange_cipher_groups.SetEnabled({
        webrtc::CryptoOptions::EphemeralKeyExchangeCipherGroups::
            kX25519_MLKEM768,
    });
    config.crypto_options = options;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    options.ephemeral_key_exchange_cipher_groups.SetEnabled({
        webrtc::CryptoOptions::EphemeralKeyExchangeCipherGroups::kSECP521R1,
    });
    config.crypto_options = options;

    RTCError error = pc_->SetConfiguration(config);
    EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
  }
  {
    RTCConfiguration config;
    config.sdp_semantics = sdp_semantics_;
    CryptoOptions options;
    options.srtp.cryptex_policy =
        CryptoOptions::Srtp::CryptexPolicy::kNegotiate;
    config.crypto_options = options;

    CreatePeerConnection(config);

    std::unique_ptr<SessionDescriptionInterface> offer;
    ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
    EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

    options.srtp.cryptex_policy = CryptoOptions::Srtp::CryptexPolicy::kRequire;
    config.crypto_options = options;

    RTCError error = pc_->SetConfiguration(config);
    EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
  }
}

// Test that PeerConnection::Close changes the states to closed and all remote
// tracks change state to ended.
TEST_P(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
  // Initialize a PeerConnection and negotiate local and remote session
  // description.
  InitiateCall();

  // With Plan B, verify the stream count. The analog with Unified Plan is the
  // RtpTransceiver count.
  if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    ASSERT_EQ(1u, pc_->local_streams()->count());
    ASSERT_EQ(1u, pc_->remote_streams()->count());
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
  } else {
    ASSERT_EQ(2u, pc_->GetTransceivers().size());
  }

  pc_->Close();

  EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
  EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
            pc_->ice_connection_state());
  EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
            pc_->ice_gathering_state());

  if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
    RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
    EXPECT_EQ(1u, pc_->local_streams()->count());
    EXPECT_EQ(1u, pc_->remote_streams()->count());
    RTC_ALLOW_PLAN_B_DEPRECATION_END();
  } else {
    // Verify that the RtpTransceivers are still returned.
    EXPECT_EQ(2u, pc_->GetTransceivers().size());
  }

  auto audio_receiver = GetFirstReceiverOfType(MediaType::AUDIO);
  auto video_receiver = GetFirstReceiverOfType(MediaType::VIDEO);
  if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
    ASSERT_TRUE(audio_receiver);
    ASSERT_TRUE(video_receiver);
    // Track state may be updated asynchronously.
    EXPECT_THAT(WaitUntil([&] { return audio_receiver->track()->state(); },
                          Eq(MediaStreamTrackInterface::kEnded),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
    EXPECT_THAT(WaitUntil([&] { return video_receiver->track()->state(); },
                          Eq(MediaStreamTrackInterface::kEnded),
                          {.timeout = TimeDelta::Millis(kTimeout)}),
                IsRtcOk());
  } else {
    ASSERT_FALSE(audio_receiver);
    ASSERT_FALSE(video_receiver);
  }
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Test that PeerConnection methods fails gracefully after
// PeerConnection::Close has been called.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, CloseAndTestMethods) {
  CreatePeerConnectionWithoutDtls();
  AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
  CreateOfferAsRemoteDescription();
  CreateAnswerAsLocalDescription();

  ASSERT_EQ(1u, pc_->local_streams()->count());
  scoped_refptr<MediaStreamInterface> local_stream(pc_->local_streams()->at(0));

  pc_->Close();

  pc_->RemoveStream(local_stream.get());
  EXPECT_FALSE(pc_->AddStream(local_stream.get()));

  EXPECT_FALSE(pc_->CreateDataChannelOrError("test", nullptr).ok());

  EXPECT_TRUE(pc_->local_description() != nullptr);
  EXPECT_TRUE(pc_->remote_description() != nullptr);

  std::unique_ptr<SessionDescriptionInterface> offer;
  EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
  std::unique_ptr<SessionDescriptionInterface> answer;
  EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));

  std::string sdp;
  ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
  std::unique_ptr<SessionDescriptionInterface> remote_offer(
      CreateSessionDescription(SdpType::kOffer, sdp));
  EXPECT_FALSE(DoSetRemoteDescription(std::move(remote_offer)));

  ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
  std::unique_ptr<SessionDescriptionInterface> local_offer(
      CreateSessionDescription(SdpType::kOffer, sdp));
  EXPECT_FALSE(DoSetLocalDescription(std::move(local_offer)));
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test that GetStats can still be called after PeerConnection::Close.
TEST_P(PeerConnectionInterfaceTest, CloseAndGetStats) {
  InitiateCall();
  pc_->Close();
  DoGetRTCStats();
}

// NOTE: The series of tests below come from what used to be
// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
// setting a remote or local description has the expected effects.

// This test verifies that the remote MediaStreams corresponding to a received
// SDP string is created. In this test the two separate MediaStreams are
// signaled.
TEST_P(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());

  scoped_refptr<StreamCollection> reference(
      CreateStreamCollection(1, 1, worker_thread_.get()));
  RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
  EXPECT_TRUE(
      CompareStreamCollections(observer_.remote_streams(), reference.get()));
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  RTC_ALLOW_PLAN_B_DEPRECATION_END();
  EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);

  // Create a session description based on another SDP with another
  // MediaStream.
  CreateAndSetRemoteOffer(GetSdpStringWithStream1And2());

  scoped_refptr<StreamCollection> reference2(
      CreateStreamCollection(2, 1, worker_thread_.get()));
  RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
  EXPECT_TRUE(
      CompareStreamCollections(observer_.remote_streams(), reference2.get()));
  RTC_ALLOW_PLAN_B_DEPRECATION_END();
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// This test verifies that when remote tracks are added/removed from SDP, the
// created remote streams are updated appropriately.
// Don't run under Unified Plan since this test uses Plan B SDP to test Plan B
// specific behavior.
TEST_F(PeerConnectionInterfaceTestPlanB,
       AddRemoveTrackFromExistingRemoteMediaStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
      CreateSessionDescriptionAndReference(1, 1);
  EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1)));
  EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
                                       reference_collection_.get()));

  // Add extra audio and video tracks to the same MediaStream.
  std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
      CreateSessionDescriptionAndReference(2, 2);
  EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1_two_tracks)));
  EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
                                       reference_collection_.get()));
  scoped_refptr<AudioTrackInterface> audio_track2 =
      observer_.remote_streams()->at(0)->GetAudioTracks()[1];
  EXPECT_EQ(MediaStreamTrackInterface::kLive, audio_track2->state());
  scoped_refptr<VideoTrackInterface> video_track2 =
      observer_.remote_streams()->at(0)->GetVideoTracks()[1];
  EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track2->state());

  // Remove the extra audio and video tracks.
  std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
      CreateSessionDescriptionAndReference(1, 1);
  MockTrackObserver audio_track_observer(audio_track2.get());
  MockTrackObserver video_track_observer(video_track2.get());

  EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
  EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
  EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms2)));
  EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
                                       reference_collection_.get()));
  // Track state may be updated asynchronously.
  EXPECT_THAT(WaitUntil([&] { return audio_track2->state(); },
                        Eq(MediaStreamTrackInterface::kEnded),
                        {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return video_track2->state(); },
                        Eq(MediaStreamTrackInterface::kEnded),
                        {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// This tests that remote tracks are ended if a local session description is set
// that rejects the media content type.
TEST_P(PeerConnectionInterfaceTest, RejectMediaContent) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  // First create and set a remote offer, then reject its video content in our
  // answer.
  CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
  auto audio_receiver = GetFirstReceiverOfType(MediaType::AUDIO);
  ASSERT_TRUE(audio_receiver);
  auto video_receiver = GetFirstReceiverOfType(MediaType::VIDEO);
  ASSERT_TRUE(video_receiver);

  scoped_refptr<MediaStreamTrackInterface> remote_audio =
      audio_receiver->track();
  EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_audio->state());
  scoped_refptr<MediaStreamTrackInterface> remote_video =
      video_receiver->track();
  EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_video->state());

  std::unique_ptr<SessionDescriptionInterface> local_answer;
  EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
  ContentInfo* video_info =
      local_answer->description()->GetContentByName("video");
  video_info->rejected = true;
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
  EXPECT_EQ(MediaStreamTrackInterface::kEnded, remote_video->state());
  EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_audio->state());

  // Now create an offer where we reject both video and audio.
  std::unique_ptr<SessionDescriptionInterface> local_offer;
  EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
  video_info = local_offer->description()->GetContentByName("video");
  ASSERT_TRUE(video_info != nullptr);
  video_info->rejected = true;
  ContentInfo* audio_info =
      local_offer->description()->GetContentByName("audio");
  ASSERT_TRUE(audio_info != nullptr);
  audio_info->rejected = true;
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
  // Track state may be updated asynchronously.
  EXPECT_THAT(WaitUntil([&] { return remote_audio->state(); },
                        Eq(MediaStreamTrackInterface::kEnded),
                        {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return remote_video->state(); },
                        Eq(MediaStreamTrackInterface::kEnded),
                        {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// This tests that we won't crash if the remote track has been removed outside
// of PeerConnection and then PeerConnection tries to reject the track.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackThenRejectMediaContent) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
  remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);

  std::unique_ptr<SessionDescriptionInterface> local_answer(
      CreateSessionDescription(SdpType::kAnswer, GetSdpStringWithStream1(),
                               nullptr));
  ContentInfo* video_info =
      local_answer->description()->GetContentByName("video");
  video_info->rejected = true;
  ContentInfo* audio_info =
      local_answer->description()->GetContentByName("audio");
  audio_info->rejected = true;
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));

  // No crash is a pass.
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// This tests that if a recvonly remote description is set, no remote streams
// will be created, even if the description contains SSRCs/MSIDs.
// See: https://code.google.com/p/webrtc/issues/detail?id=5054
TEST_P(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);

  std::string recvonly_offer = GetSdpStringWithStream1();
  absl::StrReplaceAll({{kSendrecv, kRecvonly}}, &recvonly_offer);
  CreateAndSetRemoteOffer(recvonly_offer);

  RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN();
  EXPECT_EQ(0u, observer_.remote_streams()->count());
  RTC_ALLOW_PLAN_B_DEPRECATION_END();
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// This tests that a default MediaStream is created if a remote session
// description doesn't contain any streams and no MSID support.
// It also tests that the default stream is updated if a video m-line is added
// in a subsequent session description.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithoutMsidCreatesDefaultStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);

  EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
  EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
  EXPECT_EQ("default", remote_stream->id());

  CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
  ASSERT_EQ(1u, observer_.remote_streams()->count());
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
  EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
  EXPECT_EQ(MediaStreamTrackInterface::kLive,
            remote_stream->GetAudioTracks()[0]->state());
  ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
  EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
  EXPECT_EQ(MediaStreamTrackInterface::kLive,
            remote_stream->GetVideoTracks()[0]->state());
}

// This tests that a default MediaStream is created if a remote session
// description doesn't contain any streams and media direction is send only.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB,
       SendOnlySdpWithoutMsidCreatesDefaultStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);

  EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
  EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
  EXPECT_EQ("default", remote_stream->id());
}

// This tests that it won't crash when PeerConnection tries to remove
// a remote track that as already been removed from the MediaStream.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB, RemoveAlreadyGoneRemoteStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
  remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);

  CreateAndSetRemoteOffer(kSdpStringWithoutStreams);

  // No crash is a pass.
}

// This tests that a default MediaStream is created if the remote session
// description doesn't contain any streams and don't contain an indication if
// MSID is supported.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB,
       SdpWithoutMsidAndStreamsCreatesDefaultStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringWithoutStreams);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
  EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
}

// This tests that a default MediaStream is not created if the remote session
// description doesn't contain any streams but does support MSID.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithMsidDontCreatesDefaultStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
  EXPECT_EQ(0u, observer_.remote_streams()->count());
}

// This tests that when setting a new description, the old default tracks are
// not destroyed and recreated.
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB,
       DefaultTracksNotDestroyedAndRecreated) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());

  // Set the track to "disabled", then set a new description and ensure the
  // track is still disabled, which ensures it hasn't been recreated.
  remote_stream->GetAudioTracks()[0]->set_enabled(false);
  CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
  EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
}

// This tests that a default MediaStream is not created if a remote session
// description is updated to not have any MediaStreams.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB, VerifyDefaultStreamIsNotRecreated) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(GetSdpStringWithStream1());
  scoped_refptr<StreamCollection> reference(
      CreateStreamCollection(1, 1, worker_thread_.get()));
  EXPECT_TRUE(
      CompareStreamCollections(observer_.remote_streams(), reference.get()));

  CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
  EXPECT_EQ(0u, observer_.remote_streams()->count());
}

// This tests that a default MediaStream is created if a remote SDP comes from
// an endpoint that doesn't signal SSRCs, but signals media stream IDs.
TEST_F(PeerConnectionInterfaceTestPlanB,
       SdpWithMsidWithoutSsrcCreatesDefaultStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  std::string sdp_string = kSdpStringWithoutStreamsAudioOnly;
  // Add a=msid lines to simulate a Unified Plan endpoint that only
  // signals stream IDs with a=msid lines.
  sdp_string.append("a=msid:audio_stream_id audio_track_id\n");

  CreateAndSetRemoteOffer(sdp_string);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  EXPECT_EQ("default", remote_stream->id());
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
}

// This tests that when a Plan B endpoint receives an SDP that signals no media
// stream IDs indicated by the special character "-" in the a=msid line, that
// a default stream ID will be used for the MediaStream ID. This can occur
// when a Unified Plan endpoint signals no media stream IDs, but signals both
// a=ssrc msid and a=msid lines for interop signaling with Plan B.
TEST_F(PeerConnectionInterfaceTestPlanB,
       SdpWithEmptyMsidAndSsrcCreatesDefaultStreamId) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  // Add a a=msid line to the SDP. This is prioritized when parsing the SDP, so
  // the sender's stream ID will be interpreted as no stream IDs.
  std::string sdp_string = kSdpStringWithStream1AudioTrackOnly;
  sdp_string.append("a=msid:- audiotrack0\n");

  CreateAndSetRemoteOffer(sdp_string);

  ASSERT_EQ(1u, observer_.remote_streams()->count());
  // Because SSRCs are signaled the track ID will be what was signaled in the
  // a=msid line.
  EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
  MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
  EXPECT_EQ("default", remote_stream->id());
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());

  // Previously a bug ocurred when setting the remote description a second time.
  // This is because we checked equality of the remote StreamParams stream ID
  // (empty), and the previously set stream ID for the remote sender
  // ("default"). This cause a track to be removed, then added, when really
  // nothing should occur because it is the same track.
  CreateAndSetRemoteOffer(sdp_string);
  EXPECT_EQ(0u, observer_.remove_track_events_.size());
  EXPECT_EQ(1u, observer_.add_track_events_.size());
  EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
  remote_stream = observer_.remote_streams()->at(0);
  EXPECT_EQ("default", remote_stream->id());
  ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
}

// This tests that an RtpSender is created when the local description is set
// after adding a local stream.
// TODO(deadbeef): This test and the one below it need to be updated when
// an RtpSender's lifetime isn't determined by when a local description is set.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB, LocalDescriptionChanged) {
  RTCConfiguration config;
  CreatePeerConnection(config);

  // Create an offer with 1 stream with 2 tracks of each type.
  scoped_refptr<StreamCollection> stream_collection =
      CreateStreamCollection(1, 2, worker_thread_.get());
  pc_->AddStream(stream_collection->at(0));
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  auto senders = pc_->GetSenders();
  EXPECT_EQ(4u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));

  // Remove an audio and video track.
  pc_->RemoveStream(stream_collection->at(0));
  stream_collection = CreateStreamCollection(1, 1, worker_thread_.get());
  pc_->AddStream(stream_collection->at(0));
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  senders = pc_->GetSenders();
  EXPECT_EQ(2u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
  EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
  EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
}

// This tests that an RtpSender is created when the local description is set
// before adding a local stream.
// Don't run under Unified Plan since this behavior is Plan B specific.
TEST_F(PeerConnectionInterfaceTestPlanB,
       AddLocalStreamAfterLocalDescriptionChanged) {
  RTCConfiguration config;
  CreatePeerConnection(config);

  scoped_refptr<StreamCollection> stream_collection =
      CreateStreamCollection(1, 2, worker_thread_.get());
  // Add a stream to create the offer, but remove it afterwards.
  pc_->AddStream(stream_collection->at(0));
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  pc_->RemoveStream(stream_collection->at(0));

  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
  auto senders = pc_->GetSenders();
  EXPECT_EQ(0u, senders.size());

  pc_->AddStream(stream_collection->at(0));
  senders = pc_->GetSenders();
  EXPECT_EQ(4u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// This tests that the expected behavior occurs if the SSRC on a local track is
// changed when SetLocalDescription is called.
TEST_P(PeerConnectionInterfaceTest,
       ChangeSsrcOnTrackInLocalSessionDescription) {
  RTCConfiguration config;
  CreatePeerConnection(config);

  AddAudioTrack(kAudioTracks[0]);
  AddVideoTrack(kVideoTracks[0]);
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  // Grab a copy of the offer before it gets passed into the PC.
  std::unique_ptr<SessionDescriptionInterface> modified_offer =
      CreateSessionDescription(SdpType::kOffer, offer->session_id(),
                               offer->session_version(),
                               offer->description()->Clone());
  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  auto senders = pc_->GetSenders();
  EXPECT_EQ(2u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));

  // Change the ssrc of the audio and video track.
  for (auto content : modified_offer->description()->contents()) {
    MediaContentDescription* desc = content.media_description();
    ASSERT_TRUE(desc);
    for (StreamParams& stream : desc->mutable_streams()) {
      for (unsigned int& ssrc : stream.ssrcs) {
        unsigned int old_ssrc = ssrc++;
        for (auto& group : stream.ssrc_groups) {
          for (unsigned int& secondary_ssrc : group.ssrcs) {
            if (secondary_ssrc == old_ssrc) {
              secondary_ssrc = ssrc;
            }
          }
        }
      }
    }
  }

  EXPECT_TRUE(DoSetLocalDescription(std::move(modified_offer)));
  senders = pc_->GetSenders();
  EXPECT_EQ(2u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
  // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
  // changed.
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// This tests that the expected behavior occurs if a new session description is
// set with the same tracks, but on a different MediaStream.
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB,
       SignalSameTracksInSeparateMediaStream) {
  RTCConfiguration config;
  CreatePeerConnection(config);

  scoped_refptr<StreamCollection> stream_collection =
      CreateStreamCollection(2, 1, worker_thread_.get());
  pc_->AddStream(stream_collection->at(0));
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  auto senders = pc_->GetSenders();
  EXPECT_EQ(2u, senders.size());
  EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
  EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));

  // Add a new MediaStream but with the same tracks as in the first stream.
  scoped_refptr<MediaStreamInterface> stream_1(
      MediaStream::Create(kStreams[1]));
  stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
  stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
  pc_->AddStream(stream_1.get());

  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));

  auto new_senders = pc_->GetSenders();
  // Should be the same senders as before, but with updated stream id.
  // Note that this behavior is subject to change in the future.
  // We may decide the PC should ignore existing tracks in AddStream.
  EXPECT_EQ(senders, new_senders);
  EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
  EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
TEST_P(PeerConnectionInterfaceTest, OnAddTrackCallback) {
  RTCConfiguration config;
  CreatePeerConnection(config);
  CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
  EXPECT_EQ(observer_.num_added_tracks_, 1);
  EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);

  // Create and set the updated remote SDP.
  CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
  EXPECT_EQ(observer_.num_added_tracks_, 2);
  EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
}

// Test that when SetConfiguration is called and the configuration is
// changing, the next offer causes an ICE restart.
TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingIceRestart) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.type = PeerConnectionInterface::kRelay;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  AddAudioTrack(kAudioTracks[0], {kStreamId1});
  AddVideoTrack(kVideoTracks[0], {kStreamId1});

  // Do initial offer/answer so there's something to restart.
  CreateOfferAsLocalDescription();
  CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());

  // Grab the ufrags.
  std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());

  // Change ICE policy, which should trigger an ICE restart on the next offer.
  config.type = PeerConnectionInterface::kAll;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  CreateOfferAsLocalDescription();

  // Grab the new ufrags.
  std::vector<std::string> subsequent_ufrags =
      GetUfrags(pc_->local_description());

  // Sanity check.
  EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
  // Check that each ufrag is different.
  for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
    EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
  }
}

// Test that when SetConfiguration is called and the configuration *isn't*
// changing, the next offer does *not* cause an ICE restart.
TEST_P(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRestart) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.type = PeerConnectionInterface::kRelay;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  AddAudioTrack(kAudioTracks[0]);
  AddVideoTrack(kVideoTracks[0]);

  // Do initial offer/answer so there's something to restart.
  CreateOfferAsLocalDescription();
  CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());

  // Grab the ufrags.
  std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());

  // Call SetConfiguration with a config identical to what the PC was
  // constructed with.
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());
  CreateOfferAsLocalDescription();

  // Grab the new ufrags.
  std::vector<std::string> subsequent_ufrags =
      GetUfrags(pc_->local_description());

  EXPECT_EQ(initial_ufrags, subsequent_ufrags);
}

// Test for a weird corner case scenario:
// 1. Audio/video session established.
// 2. SetConfiguration changes ICE config; ICE restart needed.
// 3. ICE restart initiated by remote peer, but only for one m= section.
// 4. Next createOffer should initiate an ICE restart, but only for the other
//    m= section; it would be pointless to do an ICE restart for the m= section
//    that was already restarted.
// Disabled because work on PT assignment showed that the restart tries
// to remap an RTX payload type.
// Tracking bug for PT assignment work: https://issues.webrtc.org/360058654
// The suspected bug is linked below.
// TODO(https://issues.webrtc.org/42233461): Fix PT assignment
TEST_P(PeerConnectionInterfaceTest,
       DISABLED_SetConfigurationCausingPartialIceRestart) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.type = PeerConnectionInterface::kRelay;
  CreatePeerConnection(config);
  config = pc_->GetConfiguration();
  AddAudioTrack(kAudioTracks[0], {kStreamId1});
  AddVideoTrack(kVideoTracks[0], {kStreamId1});

  // Do initial offer/answer so there's something to restart.
  CreateOfferAsLocalDescription();
  CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());

  // Change ICE policy, which should set the "needs-ice-restart" flag.
  config.type = PeerConnectionInterface::kAll;
  EXPECT_TRUE(pc_->SetConfiguration(config).ok());

  // Do ICE restart for the first m= section, initiated by remote peer.
  std::unique_ptr<SessionDescriptionInterface> remote_offer(
      CreateSessionDescription(SdpType::kOffer, GetSdpStringWithStream1(),
                               nullptr));
  ASSERT_TRUE(remote_offer);
  remote_offer->description()->transport_infos()[0].description.ice_ufrag =
      "modified";
  EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
  CreateAnswerAsLocalDescription();

  // Grab the ufrags.
  std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
  ASSERT_EQ(2U, initial_ufrags.size());

  // Create offer and grab the new ufrags.
  CreateOfferAsLocalDescription();
  std::vector<std::string> subsequent_ufrags =
      GetUfrags(pc_->local_description());
  ASSERT_EQ(2U, subsequent_ufrags.size());

  // Ensure that only the ufrag for the second m= section changed.
  EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
  EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
}

// Tests that the methods to return current/pending descriptions work as
// expected at different points in the offer/answer exchange. This test does
// one offer/answer exchange as the offerer, then another as the answerer.
TEST_P(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
  // This disables DTLS so we can apply an answer to ourselves.
  CreatePeerConnection();

  // Create initial local offer and get SDP (which will also be used as
  // answer/pranswer);
  std::unique_ptr<SessionDescriptionInterface> local_offer;
  ASSERT_TRUE(DoCreateOffer(&local_offer, nullptr));
  std::string sdp;
  EXPECT_TRUE(local_offer->ToString(&sdp));

  // Set local offer.
  SessionDescriptionInterface* local_offer_ptr = local_offer.get();
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
  EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
  EXPECT_EQ(nullptr, pc_->pending_remote_description());
  EXPECT_EQ(nullptr, pc_->current_local_description());
  EXPECT_EQ(nullptr, pc_->current_remote_description());

  // Set remote pranswer.
  std::unique_ptr<SessionDescriptionInterface> remote_pranswer(
      CreateSessionDescription(SdpType::kPrAnswer, sdp));
  SessionDescriptionInterface* remote_pranswer_ptr = remote_pranswer.get();
  EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_pranswer)));
  EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
  EXPECT_EQ(remote_pranswer_ptr, pc_->pending_remote_description());
  EXPECT_EQ(nullptr, pc_->current_local_description());
  EXPECT_EQ(nullptr, pc_->current_remote_description());

  // Set remote answer.
  std::unique_ptr<SessionDescriptionInterface> remote_answer(
      CreateSessionDescription(SdpType::kAnswer, sdp));
  SessionDescriptionInterface* remote_answer_ptr = remote_answer.get();
  EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_answer)));
  EXPECT_EQ(nullptr, pc_->pending_local_description());
  EXPECT_EQ(nullptr, pc_->pending_remote_description());
  EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
  EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());

  // Set remote offer.
  std::unique_ptr<SessionDescriptionInterface> remote_offer(
      CreateSessionDescription(SdpType::kOffer, sdp));
  SessionDescriptionInterface* remote_offer_ptr = remote_offer.get();
  EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
  EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
  EXPECT_EQ(nullptr, pc_->pending_local_description());
  EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
  EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());

  // Set local pranswer.
  std::unique_ptr<SessionDescriptionInterface> local_pranswer(
      CreateSessionDescription(SdpType::kPrAnswer, sdp));
  SessionDescriptionInterface* local_pranswer_ptr = local_pranswer.get();
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_pranswer)));
  EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
  EXPECT_EQ(local_pranswer_ptr, pc_->pending_local_description());
  EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
  EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());

  // Set local answer.
  std::unique_ptr<SessionDescriptionInterface> local_answer(
      CreateSessionDescription(SdpType::kAnswer, sdp));
  SessionDescriptionInterface* local_answer_ptr = local_answer.get();
  EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
  EXPECT_EQ(nullptr, pc_->pending_remote_description());
  EXPECT_EQ(nullptr, pc_->pending_local_description());
  EXPECT_EQ(remote_offer_ptr, pc_->current_remote_description());
  EXPECT_EQ(local_answer_ptr, pc_->current_local_description());
}

// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
// after the PeerConnection is closed.
// This version tests the StartRtcEventLog version that receives an object
// of type `RtcEventLogOutput`.
TEST_P(PeerConnectionInterfaceTest,
       StartAndStopLoggingToOutputAfterPeerConnectionClosed) {
  CreatePeerConnection();
  // The RtcEventLog will be reset when the PeerConnection is closed.
  pc_->Close();

  EXPECT_FALSE(pc_->StartRtcEventLog(std::make_unique<RtcEventLogOutputNull>(),
                                     RtcEventLog::kImmediateOutput));
  pc_->StopRtcEventLog();
}

// Test that generated offers/answers include "ice-option:trickle".
TEST_P(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
  CreatePeerConnection();

  // First, create an offer with audio/video.
  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 1;
  options.offer_to_receive_video = 1;
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, &options));
  SessionDescription* desc = offer->description();
  ASSERT_EQ(2u, desc->transport_infos().size());
  EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
  EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));

  // Apply the offer as a remote description, then create an answer.
  EXPECT_FALSE(pc_->can_trickle_ice_candidates());
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
  ASSERT_TRUE(pc_->can_trickle_ice_candidates());
  EXPECT_TRUE(*(pc_->can_trickle_ice_candidates()));
  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, &options));
  desc = answer->description();
  ASSERT_EQ(2u, desc->transport_infos().size());
  EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
  EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
}

// Test that ICE renomination isn't offered if it's not enabled in the PC's
// RTCConfiguration.
TEST_P(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.enable_ice_renomination = false;
  CreatePeerConnection(config);
  AddAudioTrack("foo");

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  SessionDescription* desc = offer->description();
  EXPECT_EQ(1u, desc->transport_infos().size());
  EXPECT_FALSE(
      desc->transport_infos()[0].description.GetIceParameters().renomination);
}

// Test that the ICE renomination option is present in generated offers/answers
// if it's enabled in the PC's RTCConfiguration.
TEST_P(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.enable_ice_renomination = true;
  CreatePeerConnection(config);
  AddAudioTrack("foo");

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  SessionDescription* desc = offer->description();
  EXPECT_EQ(1u, desc->transport_infos().size());
  EXPECT_TRUE(
      desc->transport_infos()[0].description.GetIceParameters().renomination);

  // Set the offer as a remote description, then create an answer and ensure it
  // has the renomination flag too.
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
  desc = answer->description();
  EXPECT_EQ(1u, desc->transport_infos().size());
  EXPECT_TRUE(
      desc->transport_infos()[0].description.GetIceParameters().renomination);
}

// Test that if CreateOffer is called with the deprecated "offer to receive
// audio/video" constraints, they're processed and result in an offer with
// audio/video sections just as if RTCOfferAnswerOptions had been used.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
  CreatePeerConnection();

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 1;
  options.offer_to_receive_video = 1;
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, &options));

  SessionDescription* desc = offer->description();
  const ContentInfo* audio = GetFirstAudioContent(desc);
  const ContentInfo* video = GetFirstVideoContent(desc);
  ASSERT_NE(nullptr, audio);
  ASSERT_NE(nullptr, video);
  EXPECT_FALSE(audio->rejected);
  EXPECT_FALSE(video->rejected);
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// Test that if CreateAnswer is called with the deprecated "offer to receive
// audio/video" constraints, they're processed and can be used to reject an
// offered m= section just as can be done with RTCOfferAnswerOptions;
// Don't run under Unified Plan since this behavior is not supported.
TEST_F(PeerConnectionInterfaceTestPlanB,
       CreateAnswerWithOfferToReceiveConstraints) {
  CreatePeerConnection();

  // First, create an offer with audio/video and apply it as a remote
  // description.
  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio = 1;
  options.offer_to_receive_video = 1;
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, &options));
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));

  // Now create answer that rejects audio/video.
  options.offer_to_receive_audio = 0;
  options.offer_to_receive_video = 0;
  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, &options));

  SessionDescription* desc = answer->description();
  const ContentInfo* audio = GetFirstAudioContent(desc);
  const ContentInfo* video = GetFirstVideoContent(desc);
  ASSERT_NE(nullptr, audio);
  ASSERT_NE(nullptr, video);
  EXPECT_TRUE(audio->rejected);
  EXPECT_TRUE(video->rejected);
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Test that negotiation can succeed with a data channel only, and with the max
// bundle policy. Previously there was a bug that prevented this.
#ifdef WEBRTC_HAVE_SCTP
TEST_P(PeerConnectionInterfaceTest, DataChannelOnlyOfferWithMaxBundlePolicy) {
#else
TEST_P(PeerConnectionInterfaceTest,
       DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy) {
#endif  // WEBRTC_HAVE_SCTP
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = sdp_semantics_;
  config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
  CreatePeerConnection(config);

  // First, create an offer with only a data channel and apply it as a remote
  // description.
  pc_->CreateDataChannelOrError("test", nullptr);
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));

  // Create and set answer as well.
  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.start_bitrate_bps = 100000;
  EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.min_bitrate_bps = -1;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.min_bitrate_bps = 5;
  bitrate.start_bitrate_bps = 3;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.start_bitrate_bps = -1;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.start_bitrate_bps = 10;
  bitrate.max_bitrate_bps = 8;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.min_bitrate_bps = 10;
  bitrate.max_bitrate_bps = 8;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.max_bitrate_bps = -1;
  EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
}

// The current bitrate from BitrateSettings is currently clamped
// by Call's BitrateConstraints, which comes from the SDP or a default value.
// This test checks that a call to SetBitrate with a current bitrate that will
// be clamped succeeds.
TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
  CreatePeerConnection();
  BitrateSettings bitrate;
  bitrate.start_bitrate_bps = 1;
  EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
}

TEST_P(PeerConnectionInterfaceTest, SetBitrateAfterCloseFails) {
  CreatePeerConnection();
  pc_->Close();
  BitrateSettings bitrate;
  bitrate.start_bitrate_bps = 1;
  auto ret = pc_->SetBitrate(bitrate);
  EXPECT_FALSE(ret.ok());
  EXPECT_EQ(RTCErrorType::INVALID_STATE, ret.type());
}

// The following tests verify that the offer can be created correctly.
TEST_P(PeerConnectionInterfaceTest,
       CreateOfferFailsWithInvalidOfferToReceiveAudio) {
  RTCOfferAnswerOptions rtc_options;

  // Setting offer_to_receive_audio to a value lower than kUndefined or greater
  // than kMaxOfferToReceiveMedia should be treated as invalid.
  rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
  CreatePeerConnection();
  EXPECT_FALSE(CreateOfferWithOptions(rtc_options));

  rtc_options.offer_to_receive_audio =
      RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
  EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
}

TEST_P(PeerConnectionInterfaceTest,
       CreateOfferFailsWithInvalidOfferToReceiveVideo) {
  RTCOfferAnswerOptions rtc_options;

  // Setting offer_to_receive_video to a value lower than kUndefined or greater
  // than kMaxOfferToReceiveMedia should be treated as invalid.
  rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
  CreatePeerConnection();
  EXPECT_FALSE(CreateOfferWithOptions(rtc_options));

  rtc_options.offer_to_receive_video =
      RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
  EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
}

// Test that the audio and video content will be added to an offer if both
// `offer_to_receive_audio` and `offer_to_receive_video` options are 1.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioVideoOptions) {
  RTCOfferAnswerOptions rtc_options;
  rtc_options.offer_to_receive_audio = 1;
  rtc_options.offer_to_receive_video = 1;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreatePeerConnection();
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
}

// Test that only audio content will be added to the offer if only
// `offer_to_receive_audio` options is 1.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioOnlyOptions) {
  RTCOfferAnswerOptions rtc_options;
  rtc_options.offer_to_receive_audio = 1;
  rtc_options.offer_to_receive_video = 0;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreatePeerConnection();
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
}

// Test that only video content will be added if only `offer_to_receive_video`
// options is 1.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithVideoOnlyOptions) {
  RTCOfferAnswerOptions rtc_options;
  rtc_options.offer_to_receive_audio = 0;
  rtc_options.offer_to_receive_video = 1;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreatePeerConnection();
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
}

// Test that no media content will be added to the offer if using default
// RTCOfferAnswerOptions.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithDefaultOfferAnswerOptions) {
  RTCOfferAnswerOptions rtc_options;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreatePeerConnection();
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
}

// Test that if `ice_restart` is true, the ufrag/pwd will change, otherwise
// ufrag/pwd will be the same in the new offer.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithIceRestart) {
  CreatePeerConnection();

  RTCOfferAnswerOptions rtc_options;
  rtc_options.ice_restart = false;
  rtc_options.offer_to_receive_audio = 1;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
  std::string mid(GetFirstAudioContent(offer->description())->mid());
  auto ufrag1 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
  auto pwd1 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;

  // `ice_restart` is false, the ufrag/pwd shouldn't change.
  CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
  auto ufrag2 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
  auto pwd2 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;

  // `ice_restart` is true, the ufrag/pwd should change.
  rtc_options.ice_restart = true;
  CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
  auto ufrag3 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
  auto pwd3 =
      offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;

  EXPECT_EQ(ufrag1, ufrag2);
  EXPECT_EQ(pwd1, pwd2);
  EXPECT_NE(ufrag2, ufrag3);
  EXPECT_NE(pwd2, pwd3);
}

// Test that if `use_rtp_mux` is true, the bundling will be enabled in the
// offer; if it is false, there won't be any bundle group in the offer.
TEST_P(PeerConnectionInterfaceTest, CreateOfferWithRtpMux) {
  RTCOfferAnswerOptions rtc_options;
  rtc_options.offer_to_receive_audio = 1;
  rtc_options.offer_to_receive_video = 1;

  std::unique_ptr<SessionDescriptionInterface> offer;
  CreatePeerConnection();

  rtc_options.use_rtp_mux = true;
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
  EXPECT_TRUE(offer->description()->HasGroup(GROUP_TYPE_BUNDLE));

  rtc_options.use_rtp_mux = false;
  offer = CreateOfferWithOptions(rtc_options);
  ASSERT_THAT(offer, NotNull());
  EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
  EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
  EXPECT_FALSE(offer->description()->HasGroup(GROUP_TYPE_BUNDLE));
}

RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN()
// This test ensures OnRenegotiationNeeded is called when we add track with
// MediaStream -> AddTrack in the same way it is called when we add track with
// PeerConnection -> AddTrack.
// The test can be removed once addStream is rewritten in terms of addTrack
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
// Don't run under Unified Plan since the stream API is not available.
TEST_F(PeerConnectionInterfaceTestPlanB,
       MediaStreamAddTrackRemoveTrackRenegotiate) {
  CreatePeerConnectionWithoutDtls();
  scoped_refptr<MediaStreamInterface> stream(
      pc_factory_->CreateLocalMediaStream(kStreamId1));
  pc_->AddStream(stream.get());
  scoped_refptr<AudioTrackInterface> audio_track(
      CreateAudioTrack("audio_track"));
  scoped_refptr<VideoTrackInterface> video_track(
      CreateVideoTrack("video_track"));
  stream->AddTrack(audio_track);
  EXPECT_THAT(WaitUntil([&] { return observer_.renegotiation_needed_; },
                        IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  observer_.renegotiation_needed_ = false;

  CreateOfferReceiveAnswer();
  stream->AddTrack(video_track);
  EXPECT_THAT(WaitUntil([&] { return observer_.renegotiation_needed_; },
                        IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  observer_.renegotiation_needed_ = false;

  CreateOfferReceiveAnswer();
  stream->RemoveTrack(audio_track);
  EXPECT_THAT(WaitUntil([&] { return observer_.renegotiation_needed_; },
                        IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  observer_.renegotiation_needed_ = false;

  CreateOfferReceiveAnswer();
  stream->RemoveTrack(video_track);
  EXPECT_THAT(WaitUntil([&] { return observer_.renegotiation_needed_; },
                        IsTrue(), {.timeout = TimeDelta::Millis(kTimeout)}),
              IsRtcOk());
  observer_.renegotiation_needed_ = false;
}
RTC_ALLOW_PLAN_B_DEPRECATION_END()

// Tests that an error is returned if a description is applied that has fewer
// media sections than the existing description.
TEST_P(PeerConnectionInterfaceTest,
       MediaSectionCountEnforcedForSubsequentOffer) {
  CreatePeerConnection();
  AddAudioTrack("audio_label");
  AddVideoTrack("video_label");

  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));

  // A remote offer with fewer media sections should be rejected.
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  offer->description()->contents().pop_back();
  offer->description()->contents().pop_back();
  ASSERT_TRUE(offer->description()->contents().empty());
  EXPECT_FALSE(DoSetRemoteDescription(std::move(offer)));

  std::unique_ptr<SessionDescriptionInterface> answer;
  ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
  EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));

  // A subsequent local offer with fewer media sections should be rejected.
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  offer->description()->contents().pop_back();
  offer->description()->contents().pop_back();
  ASSERT_TRUE(offer->description()->contents().empty());
  EXPECT_FALSE(DoSetLocalDescription(std::move(offer)));
}

TEST_P(PeerConnectionInterfaceTest, ExtmapAllowMixedIsConfigurable) {
  RTCConfiguration config;
  // Default behavior is true.
  CreatePeerConnection(config);
  std::unique_ptr<SessionDescriptionInterface> offer;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_TRUE(offer->description()->extmap_allow_mixed());
  // Possible to set to false.
  config.offer_extmap_allow_mixed = false;
  CreatePeerConnection(config);
  offer = nullptr;
  ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
  EXPECT_FALSE(offer->description()->extmap_allow_mixed());
}

TEST_P(PeerConnectionInterfaceTest,
       RtpSenderSetDegradationPreferenceWithoutEncodings) {
  CreatePeerConnection();
  AddVideoTrack("video_label");

  std::vector<scoped_refptr<RtpSenderInterface>> rtp_senders =
      pc_->GetSenders();
  ASSERT_EQ(rtp_senders.size(), 1u);
  ASSERT_EQ(rtp_senders[0]->media_type(), MediaType::VIDEO);
  scoped_refptr<RtpSenderInterface> video_rtp_sender = rtp_senders[0];
  RtpParameters parameters = video_rtp_sender->GetParameters();
  ASSERT_NE(parameters.degradation_preference,
            DegradationPreference::MAINTAIN_RESOLUTION);
  parameters.degradation_preference =
      DegradationPreference::MAINTAIN_RESOLUTION;
  ASSERT_TRUE(video_rtp_sender->SetParameters(parameters).ok());

  std::unique_ptr<SessionDescriptionInterface> local_offer;
  ASSERT_TRUE(DoCreateOffer(&local_offer, nullptr));
  ASSERT_TRUE(DoSetLocalDescription(std::move(local_offer)));

  RtpParameters parameters_new = video_rtp_sender->GetParameters();
  ASSERT_EQ(parameters_new.degradation_preference,
            DegradationPreference::MAINTAIN_RESOLUTION);
}

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

class PeerConnectionMediaConfigTest : public ::testing::Test {
 protected:
  void SetUp() override {
    network_thread_ = Thread::CreateWithSocketServer();
    network_thread_->SetName("NetworkThread", nullptr);
    ASSERT_TRUE(network_thread_->Start());
    worker_thread_ = Thread::Create();
    worker_thread_->SetName("WorkerThread", nullptr);
    ASSERT_TRUE(worker_thread_->Start());
    pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest(
        network_thread_.get(), worker_thread_.get());
  }
  MediaConfig TestCreatePeerConnection(const RTCConfiguration& config) {
    PeerConnectionDependencies pc_dependencies(&observer_);
    auto result =
        pcf_->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
    EXPECT_TRUE(result.ok());
    observer_.SetPeerConnectionInterface(result.value().get());
    return result.value()->GetConfiguration().media_config;
  }

  std::unique_ptr<Thread> network_thread_;
  std::unique_ptr<Thread> worker_thread_;
  test::RunLoop signaling_thread_;
  scoped_refptr<PeerConnectionFactoryForTest> pcf_;
  MockPeerConnectionObserver observer_;
};

// This sanity check validates the test infrastructure itself.
TEST_F(PeerConnectionMediaConfigTest, TestCreateAndClose) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;
  PeerConnectionDependencies pc_dependencies(&observer_);
  auto result =
      pcf_->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
  EXPECT_TRUE(result.ok());
  observer_.SetPeerConnectionInterface(result.value().get());
  result.value()->Close();  // No abort -> ok.
  SUCCEED();
}

// This test verifies the default behaviour with no constraints and a
// default RTCConfiguration.
TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;

  const MediaConfig& media_config = TestCreatePeerConnection(config);

  EXPECT_TRUE(media_config.enable_dscp);
  EXPECT_TRUE(media_config.video.enable_cpu_adaptation);
  EXPECT_TRUE(media_config.video.enable_prerenderer_smoothing);
  EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
  EXPECT_FALSE(media_config.video.experiment_cpu_load_estimator);
}

// This test verifies that the enable_prerenderer_smoothing flag is
// propagated from RTCConfiguration to the PeerConnection.
TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;

  config.set_prerenderer_smoothing(false);
  const MediaConfig& media_config = TestCreatePeerConnection(config);

  EXPECT_FALSE(media_config.video.enable_prerenderer_smoothing);
}

// This test verifies that the experiment_cpu_load_estimator flag is
// propagated from RTCConfiguration to the PeerConnection.
TEST_F(PeerConnectionMediaConfigTest, TestEnableExperimentCpuLoadEstimator) {
  PeerConnectionInterface::RTCConfiguration config;
  config.sdp_semantics = SdpSemantics::kUnifiedPlan;

  config.set_experiment_cpu_load_estimator(true);
  const MediaConfig& media_config = TestCreatePeerConnection(config);

  EXPECT_TRUE(media_config.video.experiment_cpu_load_estimator);
}

// Tests a few random fields being different.
TEST(RTCConfigurationTest, ComparisonOperators) {
  PeerConnectionInterface::RTCConfiguration a;
  PeerConnectionInterface::RTCConfiguration b;
  EXPECT_EQ(a, b);

  PeerConnectionInterface::RTCConfiguration c;
  c.servers.push_back(PeerConnectionInterface::IceServer());
  EXPECT_NE(a, c);

  PeerConnectionInterface::RTCConfiguration d;
  d.type = PeerConnectionInterface::kRelay;
  EXPECT_NE(a, d);

  PeerConnectionInterface::RTCConfiguration e;
  e.audio_jitter_buffer_max_packets = 5;
  EXPECT_NE(a, e);

  PeerConnectionInterface::RTCConfiguration f;
  f.ice_connection_receiving_timeout = 1337;
  EXPECT_NE(a, f);

  PeerConnectionInterface::RTCConfiguration h(
      PeerConnectionInterface::RTCConfigurationType::kAggressive);
  EXPECT_NE(a, h);
}

}  // namespace
}  // namespace webrtc
