blob: 060c8afc6414e25b326cf7284c6b586e007f9829 [file] [log] [blame]
Henrik Boström933d8b02017-10-10 10:05:16 -07001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Harald Alvestrandc24a2182022-02-23 13:44:59 +000011#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Harald Alvestrandc24a2182022-02-23 13:44:59 +000013#include <cstdint>
Henrik Boström933d8b02017-10-10 10:05:16 -070014#include <memory>
Yves Gerey3e707812018-11-28 16:47:49 +010015#include <string>
16#include <utility>
Henrik Boström933d8b02017-10-10 10:05:16 -070017#include <vector>
18
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "absl/types/optional.h"
20#include "api/audio/audio_mixer.h"
Karl Wiberg1b0eae32017-10-17 14:48:54 +020021#include "api/audio_codecs/builtin_audio_decoder_factory.h"
22#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei2ff3f492018-11-22 09:00:13 +010023#include "api/create_peerconnection_factory.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070024#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "api/media_stream_interface.h"
26#include "api/media_types.h"
27#include "api/peer_connection_interface.h"
28#include "api/rtc_error.h"
29#include "api/rtp_parameters.h"
30#include "api/rtp_receiver_interface.h"
31#include "api/rtp_sender_interface.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000032#include "api/rtp_transceiver_direction.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "api/rtp_transceiver_interface.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010034#include "api/scoped_refptr.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "api/set_remote_description_observer_interface.h"
36#include "api/uma_metrics.h"
Anders Carlsson67537952018-05-03 11:28:29 +020037#include "api/video_codecs/builtin_video_decoder_factory.h"
38#include "api/video_codecs/builtin_video_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080039#include "media/base/stream_params.h"
Yves Gerey3e707812018-11-28 16:47:49 +010040#include "modules/audio_device/include/audio_device.h"
41#include "modules/audio_processing/include/audio_processing.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "p2p/base/port_allocator.h"
43#include "pc/media_session.h"
44#include "pc/peer_connection_wrapper.h"
45#include "pc/sdp_utils.h"
46#include "pc/session_description.h"
47#include "pc/test/fake_audio_capture_module.h"
48#include "pc/test/mock_peer_connection_observers.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070049#include "rtc_base/checks.h"
50#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080051#include "rtc_base/ref_counted_object.h"
52#include "rtc_base/rtc_certificate_generator.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070053#include "rtc_base/thread.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020054#include "system_wrappers/include/metrics.h"
Steve Anton9158ef62017-11-27 13:01:52 -080055#include "test/gmock.h"
Yves Gerey3e707812018-11-28 16:47:49 +010056#include "test/gtest.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070057
58// This file contains tests for RTP Media API-related behavior of
Artem Titovcfea2182021-08-10 01:22:31 +020059// `webrtc::PeerConnection`, see https://w3c.github.io/webrtc-pc/#rtp-media-api.
Henrik Boström933d8b02017-10-10 10:05:16 -070060
Steve Anton9158ef62017-11-27 13:01:52 -080061namespace webrtc {
62
63using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
64using ::testing::ElementsAre;
Steve Antonc1e6e862019-03-04 14:43:44 -080065using ::testing::Pair;
Steve Anton9158ef62017-11-27 13:01:52 -080066using ::testing::UnorderedElementsAre;
Steve Anton3172c032018-05-03 15:30:18 -070067using ::testing::Values;
Henrik Boström933d8b02017-10-10 10:05:16 -070068
Henrik Boström31638672017-11-23 17:48:32 +010069const uint32_t kDefaultTimeout = 10000u;
70
71template <typename MethodFunctor>
Niels Möller9dde1202022-03-21 10:36:32 +010072class OnSuccessObserver : public webrtc::SetRemoteDescriptionObserverInterface {
Henrik Boström31638672017-11-23 17:48:32 +010073 public:
74 explicit OnSuccessObserver(MethodFunctor on_success)
75 : on_success_(std::move(on_success)) {}
76
77 // webrtc::SetRemoteDescriptionObserverInterface implementation.
78 void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
79 RTC_CHECK(error.ok());
80 on_success_();
81 }
82
83 private:
84 MethodFunctor on_success_;
85};
86
Mirko Bonadei6a489f22019-04-09 15:11:12 +020087class PeerConnectionRtpBaseTest : public ::testing::Test {
Henrik Boström933d8b02017-10-10 10:05:16 -070088 public:
Steve Anton3172c032018-05-03 15:30:18 -070089 explicit PeerConnectionRtpBaseTest(SdpSemantics sdp_semantics)
90 : sdp_semantics_(sdp_semantics),
91 pc_factory_(
Steve Anton9158ef62017-11-27 13:01:52 -080092 CreatePeerConnectionFactory(rtc::Thread::Current(),
93 rtc::Thread::Current(),
94 rtc::Thread::Current(),
95 FakeAudioCaptureModule::Create(),
96 CreateBuiltinAudioEncoderFactory(),
97 CreateBuiltinAudioDecoderFactory(),
Anders Carlsson67537952018-05-03 11:28:29 +020098 CreateBuiltinVideoEncoderFactory(),
99 CreateBuiltinVideoDecoderFactory(),
100 nullptr /* audio_mixer */,
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700101 nullptr /* audio_processing */)) {
102 webrtc::metrics::Reset();
103 }
Henrik Boström933d8b02017-10-10 10:05:16 -0700104
Steve Anton9158ef62017-11-27 13:01:52 -0800105 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection() {
106 return CreatePeerConnection(RTCConfiguration());
107 }
108
Steve Antone831b8c2018-02-01 12:22:16 -0800109 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithPlanB() {
110 RTCConfiguration config;
Florent Castelli15a38de2022-04-06 00:38:21 +0200111 config.sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
Steve Anton3172c032018-05-03 15:30:18 -0700112 return CreatePeerConnectionInternal(config);
Steve Antone831b8c2018-02-01 12:22:16 -0800113 }
114
Steve Anton9158ef62017-11-27 13:01:52 -0800115 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithUnifiedPlan() {
116 RTCConfiguration config;
117 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
Steve Anton3172c032018-05-03 15:30:18 -0700118 return CreatePeerConnectionInternal(config);
Steve Anton9158ef62017-11-27 13:01:52 -0800119 }
120
121 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
122 const RTCConfiguration& config) {
Steve Anton3172c032018-05-03 15:30:18 -0700123 RTCConfiguration modified_config = config;
124 modified_config.sdp_semantics = sdp_semantics_;
125 return CreatePeerConnectionInternal(modified_config);
126 }
127
128 protected:
129 const SdpSemantics sdp_semantics_;
130 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
131
132 private:
133 // Private so that tests don't accidentally bypass the SdpSemantics
134 // adjustment.
135 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionInternal(
136 const RTCConfiguration& config) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200137 auto observer = std::make_unique<MockPeerConnectionObserver>();
Henrik Boström933d8b02017-10-10 10:05:16 -0700138 auto pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr,
139 observer.get());
Yves Gerey4e933292018-10-31 15:36:05 +0100140 EXPECT_TRUE(pc.get());
141 observer->SetPeerConnectionInterface(pc.get());
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200142 return std::make_unique<PeerConnectionWrapper>(pc_factory_, pc,
143 std::move(observer));
Henrik Boström933d8b02017-10-10 10:05:16 -0700144 }
Steve Anton3172c032018-05-03 15:30:18 -0700145};
Henrik Boström933d8b02017-10-10 10:05:16 -0700146
Steve Anton3172c032018-05-03 15:30:18 -0700147class PeerConnectionRtpTest
148 : public PeerConnectionRtpBaseTest,
149 public ::testing::WithParamInterface<SdpSemantics> {
Henrik Boström933d8b02017-10-10 10:05:16 -0700150 protected:
Steve Anton3172c032018-05-03 15:30:18 -0700151 PeerConnectionRtpTest() : PeerConnectionRtpBaseTest(GetParam()) {}
152};
153
154class PeerConnectionRtpTestPlanB : public PeerConnectionRtpBaseTest {
155 protected:
156 PeerConnectionRtpTestPlanB()
Florent Castelli15a38de2022-04-06 00:38:21 +0200157 : PeerConnectionRtpBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
Steve Anton3172c032018-05-03 15:30:18 -0700158};
159
160class PeerConnectionRtpTestUnifiedPlan : public PeerConnectionRtpBaseTest {
161 protected:
162 PeerConnectionRtpTestUnifiedPlan()
163 : PeerConnectionRtpBaseTest(SdpSemantics::kUnifiedPlan) {}
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +0000164
165 // Helper to emulate an SFU that rejects an offered media section
166 // in answer.
167 bool ExchangeOfferAnswerWhereRemoteStopsTransceiver(
168 PeerConnectionWrapper* caller,
169 PeerConnectionWrapper* callee,
170 size_t mid_to_stop) {
171 auto offer = caller->CreateOffer();
172 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
173 callee->SetRemoteDescription(std::move(offer));
174 EXPECT_LT(mid_to_stop, callee->pc()->GetTransceivers().size());
175 // Must use StopInternal in order to do instant reject.
176 callee->pc()->GetTransceivers()[mid_to_stop]->StopInternal();
177 auto answer = callee->CreateAnswer();
178 EXPECT_TRUE(answer);
179 bool set_local_answer =
180 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
181 EXPECT_TRUE(set_local_answer);
182 bool set_remote_answer = caller->SetRemoteDescription(std::move(answer));
183 EXPECT_TRUE(set_remote_answer);
184 return set_remote_answer;
185 }
Henrik Boström933d8b02017-10-10 10:05:16 -0700186};
187
Artem Titovcfea2182021-08-10 01:22:31 +0200188// These tests cover `webrtc::PeerConnectionObserver` callbacks firing upon
Henrik Boström31638672017-11-23 17:48:32 +0100189// setting the remote description.
Henrik Boström31638672017-11-23 17:48:32 +0100190
Steve Anton3172c032018-05-03 15:30:18 -0700191TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamFiresOnAddTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700192 auto caller = CreatePeerConnection();
193 auto callee = CreatePeerConnection();
194
Steve Anton3172c032018-05-03 15:30:18 -0700195 ASSERT_TRUE(caller->AddAudioTrack("audio_track"));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700196 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700197
Henrik Boström31638672017-11-23 17:48:32 +0100198 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Steve Anton3172c032018-05-03 15:30:18 -0700199 const auto& add_track_event = callee->observer()->add_track_events_[0];
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100200 EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
Steve Anton3172c032018-05-03 15:30:18 -0700201
Florent Castelli15a38de2022-04-06 00:38:21 +0200202 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Steve Anton3172c032018-05-03 15:30:18 -0700203 // Since we are not supporting the no stream case with Plan B, there should
204 // be a generated stream, even though we didn't set one with AddTrack.
205 ASSERT_EQ(1u, add_track_event.streams.size());
206 EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
207 } else {
208 EXPECT_EQ(0u, add_track_event.streams.size());
209 }
Henrik Boström933d8b02017-10-10 10:05:16 -0700210}
211
Steve Anton3172c032018-05-03 15:30:18 -0700212TEST_P(PeerConnectionRtpTest, AddTrackWithStreamFiresOnAddTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700213 auto caller = CreatePeerConnection();
214 auto callee = CreatePeerConnection();
215
Steve Anton3172c032018-05-03 15:30:18 -0700216 ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700217 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700218
Henrik Boström31638672017-11-23 17:48:32 +0100219 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100220 auto& add_track_event = callee->observer()->add_track_events_[0];
Henrik Boström31638672017-11-23 17:48:32 +0100221 ASSERT_EQ(add_track_event.streams.size(), 1u);
Seth Hampson13b8bad2018-03-13 16:05:28 -0700222 EXPECT_EQ("audio_stream", add_track_event.streams[0]->id());
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100223 EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
224 EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
Henrik Boström933d8b02017-10-10 10:05:16 -0700225}
226
Steve Anton3172c032018-05-03 15:30:18 -0700227TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700228 auto caller = CreatePeerConnection();
229 auto callee = CreatePeerConnection();
230
Steve Anton3172c032018-05-03 15:30:18 -0700231 auto sender = caller->AddAudioTrack("audio_track", {});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700232 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100233 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Steve Anton3172c032018-05-03 15:30:18 -0700234 ASSERT_TRUE(
235 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
236
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000237 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Seth Hampson5897a6e2018-04-03 11:16:33 -0700238 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700239
Henrik Boström31638672017-11-23 17:48:32 +0100240 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700241 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
242 callee->observer()->remove_track_events_);
243}
244
Steve Anton3172c032018-05-03 15:30:18 -0700245TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700246 auto caller = CreatePeerConnection();
247 auto callee = CreatePeerConnection();
248
Steve Anton3172c032018-05-03 15:30:18 -0700249 auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700250 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100251 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Steve Anton3172c032018-05-03 15:30:18 -0700252 ASSERT_TRUE(
253 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
254
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000255 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Seth Hampson5897a6e2018-04-03 11:16:33 -0700256 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700257
Henrik Boström31638672017-11-23 17:48:32 +0100258 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700259 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
260 callee->observer()->remove_track_events_);
Steve Anton3172c032018-05-03 15:30:18 -0700261 EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
Henrik Boström933d8b02017-10-10 10:05:16 -0700262}
263
Steve Anton3172c032018-05-03 15:30:18 -0700264TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700265 auto caller = CreatePeerConnection();
266 auto callee = CreatePeerConnection();
267
Seth Hampson845e8782018-03-02 11:34:10 -0800268 const char kSharedStreamId[] = "shared_audio_stream";
Steve Anton3172c032018-05-03 15:30:18 -0700269 auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
270 auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700271 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100272 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Steve Anton3172c032018-05-03 15:30:18 -0700273 ASSERT_TRUE(
274 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700275
276 // Remove "audio_track1".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000277 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender1).ok());
Seth Hampson5897a6e2018-04-03 11:16:33 -0700278 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100279 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700280 EXPECT_EQ(
Steve Anton9158ef62017-11-27 13:01:52 -0800281 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
Henrik Boström933d8b02017-10-10 10:05:16 -0700282 callee->observer()->add_track_events_[0].receiver},
283 callee->observer()->remove_track_events_);
Steve Anton3172c032018-05-03 15:30:18 -0700284 ASSERT_EQ(1u, callee->observer()->remote_streams()->count());
285 ASSERT_TRUE(
286 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700287
288 // Remove "audio_track2".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000289 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender2).ok());
Seth Hampson5897a6e2018-04-03 11:16:33 -0700290 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100291 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700292 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
293 callee->observer()->remove_track_events_);
Steve Anton3172c032018-05-03 15:30:18 -0700294 EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
Henrik Boström933d8b02017-10-10 10:05:16 -0700295}
296
Seth Hampson5b4f0752018-04-02 16:31:36 -0700297// Tests the edge case that if a stream ID changes for a given track that both
298// OnRemoveTrack and OnAddTrack is fired.
Steve Anton3172c032018-05-03 15:30:18 -0700299TEST_F(PeerConnectionRtpTestPlanB,
Seth Hampson5b4f0752018-04-02 16:31:36 -0700300 RemoteStreamIdChangesFiresOnRemoveAndOnAddTrack) {
301 auto caller = CreatePeerConnection();
302 auto callee = CreatePeerConnection();
303
304 const char kStreamId1[] = "stream1";
305 const char kStreamId2[] = "stream2";
Steve Anton3172c032018-05-03 15:30:18 -0700306 caller->AddAudioTrack("audio_track1", {kStreamId1});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700307 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700308 EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
309
310 // Change the stream ID of the sender in the session description.
311 auto offer = caller->CreateOfferAndSetAsLocal();
Steve Anton3172c032018-05-03 15:30:18 -0700312 auto* audio_desc =
313 cricket::GetFirstAudioContentDescription(offer->description());
Seth Hampson5b4f0752018-04-02 16:31:36 -0700314 ASSERT_EQ(audio_desc->mutable_streams().size(), 1u);
315 audio_desc->mutable_streams()[0].set_stream_ids({kStreamId2});
Steve Anton3172c032018-05-03 15:30:18 -0700316 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700317
318 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
319 EXPECT_EQ(callee->observer()->add_track_events_[1].streams[0]->id(),
320 kStreamId2);
321 ASSERT_EQ(callee->observer()->remove_track_events_.size(), 1u);
322 EXPECT_EQ(callee->observer()->remove_track_events_[0]->streams()[0]->id(),
323 kStreamId1);
324}
325
Steve Anton8b815cd2018-02-16 16:14:42 -0800326// Tests that setting a remote description with sending transceivers will fire
327// the OnTrack callback for each transceiver and setting a remote description
Seth Hampson5b4f0752018-04-02 16:31:36 -0700328// with receive only transceivers will not call OnTrack. One transceiver is
329// created without any stream_ids, while the other is created with multiple
330// stream_ids.
Steve Anton3172c032018-05-03 15:30:18 -0700331TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverCallsOnTrack) {
Seth Hampson5b4f0752018-04-02 16:31:36 -0700332 const std::string kStreamId1 = "video_stream1";
333 const std::string kStreamId2 = "video_stream2";
Steve Anton3172c032018-05-03 15:30:18 -0700334 auto caller = CreatePeerConnection();
335 auto callee = CreatePeerConnection();
Steve Anton8b815cd2018-02-16 16:14:42 -0800336
337 auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Seth Hampson5b4f0752018-04-02 16:31:36 -0700338 RtpTransceiverInit video_transceiver_init;
339 video_transceiver_init.stream_ids = {kStreamId1, kStreamId2};
340 auto video_transceiver =
341 caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, video_transceiver_init);
Steve Anton8b815cd2018-02-16 16:14:42 -0800342
343 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
344
345 ASSERT_EQ(0u, caller->observer()->on_track_transceivers_.size());
346 ASSERT_EQ(2u, callee->observer()->on_track_transceivers_.size());
347 EXPECT_EQ(audio_transceiver->mid(),
348 callee->pc()->GetTransceivers()[0]->mid());
349 EXPECT_EQ(video_transceiver->mid(),
350 callee->pc()->GetTransceivers()[1]->mid());
Seth Hampson5b4f0752018-04-02 16:31:36 -0700351 std::vector<rtc::scoped_refptr<MediaStreamInterface>> audio_streams =
352 callee->pc()->GetTransceivers()[0]->receiver()->streams();
353 std::vector<rtc::scoped_refptr<MediaStreamInterface>> video_streams =
354 callee->pc()->GetTransceivers()[1]->receiver()->streams();
355 ASSERT_EQ(0u, audio_streams.size());
356 ASSERT_EQ(2u, video_streams.size());
357 EXPECT_EQ(kStreamId1, video_streams[0]->id());
358 EXPECT_EQ(kStreamId2, video_streams[1]->id());
Steve Anton8b815cd2018-02-16 16:14:42 -0800359}
360
361// Test that doing additional offer/answer exchanges with no changes to tracks
362// will cause no additional OnTrack calls after the tracks have been negotiated.
Steve Anton3172c032018-05-03 15:30:18 -0700363TEST_F(PeerConnectionRtpTestUnifiedPlan, ReofferDoesNotCallOnTrack) {
364 auto caller = CreatePeerConnection();
365 auto callee = CreatePeerConnection();
Steve Anton8b815cd2018-02-16 16:14:42 -0800366
367 caller->AddAudioTrack("audio");
368 callee->AddAudioTrack("audio");
369
370 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
371 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
372 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
373
374 // If caller reoffers with no changes expect no additional OnTrack calls.
375 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
376 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
377 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
378
379 // Also if callee reoffers with no changes expect no additional OnTrack calls.
380 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
381 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
382 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
383}
384
385// Test that OnTrack is called when the transceiver direction changes to send
386// the track.
Steve Anton3172c032018-05-03 15:30:18 -0700387TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionCallsOnTrack) {
388 auto caller = CreatePeerConnection();
389 auto callee = CreatePeerConnection();
Steve Anton8b815cd2018-02-16 16:14:42 -0800390
391 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Harald Alvestrand6060df52020-08-11 09:54:02 +0200392 EXPECT_TRUE(
393 transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
394 .ok());
Steve Anton8b815cd2018-02-16 16:14:42 -0800395 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
396 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
397 EXPECT_EQ(0u, callee->observer()->on_track_transceivers_.size());
398
Harald Alvestrand6060df52020-08-11 09:54:02 +0200399 EXPECT_TRUE(
400 transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendOnly)
401 .ok());
Steve Anton8b815cd2018-02-16 16:14:42 -0800402 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
403 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
404 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
405
406 // If the direction changes but it is still receiving on the remote side, then
407 // OnTrack should not be fired again.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200408 EXPECT_TRUE(
409 transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv)
410 .ok());
Steve Anton8b815cd2018-02-16 16:14:42 -0800411 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
412 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
413 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
414}
415
416// Test that OnTrack is called twice when a sendrecv call is started, the callee
417// changes the direction to inactive, then changes it back to sendrecv.
Steve Anton3172c032018-05-03 15:30:18 -0700418TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionHoldCallsOnTrackTwice) {
419 auto caller = CreatePeerConnection();
420 auto callee = CreatePeerConnection();
Steve Anton8b815cd2018-02-16 16:14:42 -0800421
422 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
423
424 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
425 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
426 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
427
428 // Put the call on hold by no longer receiving the track.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200429 EXPECT_TRUE(callee->pc()
430 ->GetTransceivers()[0]
431 ->SetDirectionWithError(RtpTransceiverDirection::kInactive)
432 .ok());
Steve Anton8b815cd2018-02-16 16:14:42 -0800433
434 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
435 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
436 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
437
438 // Resume the call by changing the direction to recvonly. This should call
439 // OnTrack again on the callee side.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200440 EXPECT_TRUE(callee->pc()
441 ->GetTransceivers()[0]
442 ->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly)
443 .ok());
Steve Anton8b815cd2018-02-16 16:14:42 -0800444
445 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
446 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
447 EXPECT_EQ(2u, callee->observer()->on_track_transceivers_.size());
448}
449
Steve Anton3172c032018-05-03 15:30:18 -0700450// Test that setting a remote offer twice with no answer in the middle results
Steve Anton0f5400a2018-07-17 14:25:36 -0700451// in OnAddTrack being fired only once.
Steve Anton3172c032018-05-03 15:30:18 -0700452TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton0f5400a2018-07-17 14:25:36 -0700453 ApplyTwoRemoteOffersWithNoAnswerResultsInOneAddTrackEvent) {
Henrik Boström31638672017-11-23 17:48:32 +0100454 auto caller = CreatePeerConnection();
455 auto callee = CreatePeerConnection();
456
Steve Anton3172c032018-05-03 15:30:18 -0700457 caller->AddAudioTrack("audio_track", {});
458
Amit Hilbuchae3df542019-01-07 12:13:08 -0800459 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Steve Anton3172c032018-05-03 15:30:18 -0700460 ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
461
Amit Hilbuchae3df542019-01-07 12:13:08 -0800462 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Steve Anton0f5400a2018-07-17 14:25:36 -0700463 EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
Steve Anton3172c032018-05-03 15:30:18 -0700464}
465
466// Test that setting a remote offer twice with no answer in the middle and the
467// track being removed between the two offers results in OnAddTrack being called
Steve Anton0f5400a2018-07-17 14:25:36 -0700468// once the first time and OnRemoveTrack being called once the second time.
Steve Anton3172c032018-05-03 15:30:18 -0700469TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton0f5400a2018-07-17 14:25:36 -0700470 ApplyRemoteOfferAddThenRemoteOfferRemoveResultsInOneRemoveTrackEvent) {
Steve Anton3172c032018-05-03 15:30:18 -0700471 auto caller = CreatePeerConnection();
472 auto callee = CreatePeerConnection();
473
474 auto sender = caller->AddAudioTrack("audio_track", {});
475
Amit Hilbuchae3df542019-01-07 12:13:08 -0800476 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Steve Anton3172c032018-05-03 15:30:18 -0700477 ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
Steve Anton0f5400a2018-07-17 14:25:36 -0700478 EXPECT_EQ(0u, callee->observer()->remove_track_events_.size());
Steve Anton3172c032018-05-03 15:30:18 -0700479
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000480 caller->pc()->RemoveTrackOrError(sender);
Steve Anton3172c032018-05-03 15:30:18 -0700481
Amit Hilbuchae3df542019-01-07 12:13:08 -0800482 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Steve Anton3172c032018-05-03 15:30:18 -0700483 EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
Steve Anton0f5400a2018-07-17 14:25:36 -0700484 EXPECT_EQ(1u, callee->observer()->remove_track_events_.size());
485}
486
487// Test that changing the direction from receiving to not receiving between
488// setting the remote offer and creating / setting the local answer results in
489// a remove track event when SetLocalDescription is called.
490TEST_F(PeerConnectionRtpTestUnifiedPlan,
491 ChangeDirectionInAnswerResultsInRemoveTrackEvent) {
492 auto caller = CreatePeerConnection();
493 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
494 auto callee = CreatePeerConnection();
495 callee->AddAudioTrack("audio_track", {});
496
497 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
498 EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
Steve Anton3172c032018-05-03 15:30:18 -0700499 EXPECT_EQ(0u, callee->observer()->remove_track_events_.size());
Steve Anton0f5400a2018-07-17 14:25:36 -0700500
501 auto callee_transceiver = callee->pc()->GetTransceivers()[0];
Harald Alvestrand6060df52020-08-11 09:54:02 +0200502 EXPECT_TRUE(callee_transceiver
503 ->SetDirectionWithError(RtpTransceiverDirection::kSendOnly)
504 .ok());
Steve Anton0f5400a2018-07-17 14:25:36 -0700505
506 ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
507 EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
508 EXPECT_EQ(1u, callee->observer()->remove_track_events_.size());
Steve Anton3172c032018-05-03 15:30:18 -0700509}
510
Henrik Boströmafa07dd2018-12-20 11:06:02 +0100511TEST_F(PeerConnectionRtpTestUnifiedPlan, ChangeMsidWhileReceiving) {
512 auto caller = CreatePeerConnection();
513 caller->AddAudioTrack("audio_track", {"stream1"});
514 auto callee = CreatePeerConnection();
Amit Hilbuchae3df542019-01-07 12:13:08 -0800515 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boströmafa07dd2018-12-20 11:06:02 +0100516
517 ASSERT_EQ(1u, callee->observer()->on_track_transceivers_.size());
518 auto transceiver = callee->observer()->on_track_transceivers_[0];
519 ASSERT_EQ(1u, transceiver->receiver()->streams().size());
520 EXPECT_EQ("stream1", transceiver->receiver()->streams()[0]->id());
521
Amit Hilbuchae3df542019-01-07 12:13:08 -0800522 ASSERT_TRUE(callee->CreateAnswerAndSetAsLocal());
Henrik Boströmafa07dd2018-12-20 11:06:02 +0100523
524 // Change the stream ID in the offer.
Guido Urdaneta1ff16c82019-05-20 19:31:53 +0200525 caller->pc()->GetSenders()[0]->SetStreams({"stream2"});
526 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boströmafa07dd2018-12-20 11:06:02 +0100527 ASSERT_EQ(1u, transceiver->receiver()->streams().size());
528 EXPECT_EQ("stream2", transceiver->receiver()->streams()[0]->id());
529}
530
Steve Anton3172c032018-05-03 15:30:18 -0700531// These tests examine the state of the peer connection as a result of
532// performing SetRemoteDescription().
533
534TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamAddsReceiver) {
535 auto caller = CreatePeerConnection();
536 auto callee = CreatePeerConnection();
537
538 ASSERT_TRUE(caller->AddAudioTrack("audio_track", {}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700539 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100540
541 EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
542 auto receiver_added = callee->pc()->GetReceivers()[0];
543 EXPECT_EQ("audio_track", receiver_added->track()->id());
Steve Anton3172c032018-05-03 15:30:18 -0700544
Florent Castelli15a38de2022-04-06 00:38:21 +0200545 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Steve Anton3172c032018-05-03 15:30:18 -0700546 // Since we are not supporting the no stream case with Plan B, there should
547 // be a generated stream, even though we didn't set one with AddTrack.
548 ASSERT_EQ(1u, receiver_added->streams().size());
549 EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
550 } else {
551 EXPECT_EQ(0u, receiver_added->streams().size());
552 }
Henrik Boström31638672017-11-23 17:48:32 +0100553}
554
Steve Anton3172c032018-05-03 15:30:18 -0700555TEST_P(PeerConnectionRtpTest, AddTrackWithStreamAddsReceiver) {
Henrik Boström31638672017-11-23 17:48:32 +0100556 auto caller = CreatePeerConnection();
557 auto callee = CreatePeerConnection();
558
Steve Anton3172c032018-05-03 15:30:18 -0700559 ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700560 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100561
562 EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
563 auto receiver_added = callee->pc()->GetReceivers()[0];
564 EXPECT_EQ("audio_track", receiver_added->track()->id());
565 EXPECT_EQ(receiver_added->streams().size(), 1u);
Seth Hampson13b8bad2018-03-13 16:05:28 -0700566 EXPECT_EQ("audio_stream", receiver_added->streams()[0]->id());
Henrik Boström31638672017-11-23 17:48:32 +0100567 EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
568}
569
Steve Anton3172c032018-05-03 15:30:18 -0700570TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamRemovesReceiver) {
Henrik Boström31638672017-11-23 17:48:32 +0100571 auto caller = CreatePeerConnection();
572 auto callee = CreatePeerConnection();
573
Steve Anton3172c032018-05-03 15:30:18 -0700574 auto sender = caller->AddAudioTrack("audio_track", {});
Henrik Boström31638672017-11-23 17:48:32 +0100575 ASSERT_TRUE(sender);
Steve Anton3172c032018-05-03 15:30:18 -0700576 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
577
Henrik Boström31638672017-11-23 17:48:32 +0100578 ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
579 auto receiver = callee->pc()->GetReceivers()[0];
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000580 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Steve Anton3172c032018-05-03 15:30:18 -0700581 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boström31638672017-11-23 17:48:32 +0100582
Steve Anton3172c032018-05-03 15:30:18 -0700583 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
584 // With Unified Plan the receiver stays but the transceiver transitions to
585 // inactive.
586 ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
587 EXPECT_EQ(RtpTransceiverDirection::kInactive,
588 callee->pc()->GetTransceivers()[0]->current_direction());
589 } else {
590 // With Plan B the receiver is removed.
591 ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
592 }
Henrik Boström31638672017-11-23 17:48:32 +0100593}
594
Steve Anton3172c032018-05-03 15:30:18 -0700595TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamRemovesReceiver) {
Henrik Boström31638672017-11-23 17:48:32 +0100596 auto caller = CreatePeerConnection();
597 auto callee = CreatePeerConnection();
598
Steve Anton3172c032018-05-03 15:30:18 -0700599 auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
Henrik Boström31638672017-11-23 17:48:32 +0100600 ASSERT_TRUE(sender);
Steve Anton3172c032018-05-03 15:30:18 -0700601 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boström31638672017-11-23 17:48:32 +0100602 ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
603 auto receiver = callee->pc()->GetReceivers()[0];
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000604 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Steve Anton3172c032018-05-03 15:30:18 -0700605 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boström31638672017-11-23 17:48:32 +0100606
Steve Anton3172c032018-05-03 15:30:18 -0700607 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
608 // With Unified Plan the receiver stays but the transceiver transitions to
609 // inactive.
610 EXPECT_EQ(1u, callee->pc()->GetReceivers().size());
611 EXPECT_EQ(RtpTransceiverDirection::kInactive,
612 callee->pc()->GetTransceivers()[0]->current_direction());
613 } else {
614 // With Plan B the receiver is removed.
615 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
616 }
Henrik Boström31638672017-11-23 17:48:32 +0100617}
618
Steve Anton3172c032018-05-03 15:30:18 -0700619TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamRemovesReceiver) {
Henrik Boström31638672017-11-23 17:48:32 +0100620 auto caller = CreatePeerConnection();
621 auto callee = CreatePeerConnection();
622
Seth Hampson845e8782018-03-02 11:34:10 -0800623 const char kSharedStreamId[] = "shared_audio_stream";
Steve Anton3172c032018-05-03 15:30:18 -0700624 auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
625 auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
626 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
627 ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
Henrik Boström31638672017-11-23 17:48:32 +0100628
629 // Remove "audio_track1".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000630 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender1).ok());
Steve Anton3172c032018-05-03 15:30:18 -0700631 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
632
633 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
634 // With Unified Plan the receiver stays but the transceiver transitions to
635 // inactive.
636 ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
637 auto transceiver = callee->pc()->GetTransceivers()[0];
638 EXPECT_EQ("audio_track1", transceiver->receiver()->track()->id());
639 EXPECT_EQ(RtpTransceiverDirection::kInactive,
640 transceiver->current_direction());
641 } else {
642 // With Plan B the receiver is removed.
643 ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
644 EXPECT_EQ("audio_track2", callee->pc()->GetReceivers()[0]->track()->id());
645 }
Henrik Boström31638672017-11-23 17:48:32 +0100646
647 // Remove "audio_track2".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000648 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender2).ok());
Steve Anton3172c032018-05-03 15:30:18 -0700649 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
650
651 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
652 // With Unified Plan the receiver stays but the transceiver transitions to
653 // inactive.
654 ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
655 auto transceiver = callee->pc()->GetTransceivers()[1];
656 EXPECT_EQ("audio_track2", transceiver->receiver()->track()->id());
657 EXPECT_EQ(RtpTransceiverDirection::kInactive,
658 transceiver->current_direction());
659 } else {
660 // With Plan B the receiver is removed.
661 ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
662 }
Henrik Boström31638672017-11-23 17:48:32 +0100663}
664
Florent Castelliabe301f2018-06-12 18:33:49 +0200665TEST_P(PeerConnectionRtpTest, AudioGetParametersHasHeaderExtensions) {
666 auto caller = CreatePeerConnection();
667 auto callee = CreatePeerConnection();
668 auto sender = caller->AddAudioTrack("audio_track");
669 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
670
671 ASSERT_GT(caller->pc()->GetSenders().size(), 0u);
672 EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u);
673
674 ASSERT_GT(callee->pc()->GetReceivers().size(), 0u);
675 auto receiver = callee->pc()->GetReceivers()[0];
676 EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u);
677}
678
679TEST_P(PeerConnectionRtpTest, VideoGetParametersHasHeaderExtensions) {
680 auto caller = CreatePeerConnection();
681 auto callee = CreatePeerConnection();
682 auto sender = caller->AddVideoTrack("video_track");
683 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
684
685 ASSERT_GT(caller->pc()->GetSenders().size(), 0u);
686 EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u);
687
688 ASSERT_GT(callee->pc()->GetReceivers().size(), 0u);
689 auto receiver = callee->pc()->GetReceivers()[0];
690 EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u);
691}
692
Henrik Boström31638672017-11-23 17:48:32 +0100693// Invokes SetRemoteDescription() twice in a row without synchronizing the two
694// calls and examine the state of the peer connection inside the callbacks to
695// ensure that the second call does not occur prematurely, contaminating the
696// state of the peer connection of the first callback.
Steve Anton3172c032018-05-03 15:30:18 -0700697TEST_F(PeerConnectionRtpTestPlanB,
Henrik Boström31638672017-11-23 17:48:32 +0100698 StatesCorrelateWithSetRemoteDescriptionCall) {
699 auto caller = CreatePeerConnection();
700 auto callee = CreatePeerConnection();
701
Henrik Boström31638672017-11-23 17:48:32 +0100702 // Create SDP for adding a track and for removing it. This will be used in the
703 // first and second SetRemoteDescription() calls.
Steve Anton3172c032018-05-03 15:30:18 -0700704 auto sender = caller->AddAudioTrack("audio_track", {});
Henrik Boström31638672017-11-23 17:48:32 +0100705 auto srd1_sdp = caller->CreateOfferAndSetAsLocal();
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000706 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Henrik Boström31638672017-11-23 17:48:32 +0100707 auto srd2_sdp = caller->CreateOfferAndSetAsLocal();
708
709 // In the first SetRemoteDescription() callback, check that we have a
710 // receiver for the track.
711 auto pc = callee->pc();
712 bool srd1_callback_called = false;
713 auto srd1_callback = [&srd1_callback_called, &pc]() {
714 EXPECT_EQ(pc->GetReceivers().size(), 1u);
715 srd1_callback_called = true;
716 };
717
718 // In the second SetRemoteDescription() callback, check that the receiver has
719 // been removed.
720 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
721 // Instead, the transceiver owning the receiver will become inactive.
722 // https://crbug.com/webrtc/7600
723 bool srd2_callback_called = false;
724 auto srd2_callback = [&srd2_callback_called, &pc]() {
725 EXPECT_TRUE(pc->GetReceivers().empty());
726 srd2_callback_called = true;
727 };
728
729 // Invoke SetRemoteDescription() twice in a row without synchronizing the two
730 // calls. The callbacks verify that the two calls are synchronized, as in, the
731 // effects of the second SetRemoteDescription() call must not have happened by
732 // the time the first callback is invoked. If it has then the receiver that is
733 // added as a result of the first SetRemoteDescription() call will already
734 // have been removed as a result of the second SetRemoteDescription() call
735 // when the first callback is invoked.
736 callee->pc()->SetRemoteDescription(
737 std::move(srd1_sdp),
Niels Möllere7cc8832022-01-04 15:20:03 +0100738 rtc::make_ref_counted<OnSuccessObserver<decltype(srd1_callback)>>(
739 srd1_callback));
Henrik Boström31638672017-11-23 17:48:32 +0100740 callee->pc()->SetRemoteDescription(
741 std::move(srd2_sdp),
Niels Möllere7cc8832022-01-04 15:20:03 +0100742 rtc::make_ref_counted<OnSuccessObserver<decltype(srd2_callback)>>(
743 srd2_callback));
Henrik Boström31638672017-11-23 17:48:32 +0100744 EXPECT_TRUE_WAIT(srd1_callback_called, kDefaultTimeout);
745 EXPECT_TRUE_WAIT(srd2_callback_called, kDefaultTimeout);
746}
747
Seth Hampson5897a6e2018-04-03 11:16:33 -0700748// Tests that a remote track is created with the signaled MSIDs when they are
749// communicated with a=msid and no SSRCs are signaled at all (i.e., no a=ssrc
750// lines).
Steve Anton3172c032018-05-03 15:30:18 -0700751TEST_F(PeerConnectionRtpTestUnifiedPlan, UnsignaledSsrcCreatesReceiverStreams) {
752 auto caller = CreatePeerConnection();
753 auto callee = CreatePeerConnection();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700754 const char kStreamId1[] = "stream1";
755 const char kStreamId2[] = "stream2";
756 caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
757 {kStreamId1, kStreamId2});
758
759 auto offer = caller->CreateOfferAndSetAsLocal();
760 // Munge the offer to take out everything but the stream_ids.
761 auto contents = offer->description()->contents();
762 ASSERT_TRUE(!contents.empty());
763 ASSERT_TRUE(!contents[0].media_description()->streams().empty());
764 std::vector<std::string> stream_ids =
765 contents[0].media_description()->streams()[0].stream_ids();
766 contents[0].media_description()->mutable_streams().clear();
767 cricket::StreamParams new_stream;
768 new_stream.set_stream_ids(stream_ids);
769 contents[0].media_description()->AddStream(new_stream);
770
771 // Set the remote description and verify that the streams were added to the
772 // receiver correctly.
773 ASSERT_TRUE(
774 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
775 auto receivers = callee->pc()->GetReceivers();
776 ASSERT_EQ(receivers.size(), 1u);
777 ASSERT_EQ(receivers[0]->streams().size(), 2u);
778 EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId1);
779 EXPECT_EQ(receivers[0]->streams()[1]->id(), kStreamId2);
780}
Henrik Boströmc335b0e2021-04-08 07:25:38 +0200781TEST_F(PeerConnectionRtpTestUnifiedPlan, TracksDoNotEndWhenSsrcChanges) {
782 constexpr uint32_t kFirstMungedSsrc = 1337u;
783
784 auto caller = CreatePeerConnection();
785 auto callee = CreatePeerConnection();
786
787 // Caller offers to receive audio and video.
788 RtpTransceiverInit init;
789 init.direction = RtpTransceiverDirection::kRecvOnly;
790 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
791 caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
792
793 // Callee wants to send audio and video tracks.
794 callee->AddTrack(callee->CreateAudioTrack("audio_track"), {});
795 callee->AddTrack(callee->CreateVideoTrack("video_track"), {});
796
797 // Do inittial offer/answer exchange.
798 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
799 ASSERT_TRUE(
800 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
801 ASSERT_EQ(caller->observer()->add_track_events_.size(), 2u);
802 ASSERT_EQ(caller->pc()->GetReceivers().size(), 2u);
803
804 // Do a follow-up offer/answer exchange where the SSRCs are modified.
805 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
806 auto answer = callee->CreateAnswer();
807 auto& contents = answer->description()->contents();
808 ASSERT_TRUE(!contents.empty());
809 for (size_t i = 0; i < contents.size(); ++i) {
810 auto& mutable_streams = contents[i].media_description()->mutable_streams();
811 ASSERT_EQ(mutable_streams.size(), 1u);
812 mutable_streams[0].ssrcs = {kFirstMungedSsrc + static_cast<uint32_t>(i)};
813 }
814 ASSERT_TRUE(
815 callee->SetLocalDescription(CloneSessionDescription(answer.get())));
816 ASSERT_TRUE(
817 caller->SetRemoteDescription(CloneSessionDescription(answer.get())));
818
819 // No furher track events should fire because we never changed direction, only
820 // SSRCs.
821 ASSERT_EQ(caller->observer()->add_track_events_.size(), 2u);
822 // We should have the same number of receivers as before.
823 auto receivers = caller->pc()->GetReceivers();
824 ASSERT_EQ(receivers.size(), 2u);
825 // The tracks are still alive.
826 EXPECT_EQ(receivers[0]->track()->state(),
827 MediaStreamTrackInterface::TrackState::kLive);
828 EXPECT_EQ(receivers[1]->track()->state(),
829 MediaStreamTrackInterface::TrackState::kLive);
830}
Seth Hampson5897a6e2018-04-03 11:16:33 -0700831
Seth Hampson5b4f0752018-04-02 16:31:36 -0700832// Tests that with Unified Plan if the the stream id changes for a track when
833// when setting a new remote description, that the media stream is updated
834// appropriately for the receiver.
Steve Anton0f5400a2018-07-17 14:25:36 -0700835// TODO(https://github.com/w3c/webrtc-pc/issues/1937): Resolve spec issue or fix
836// test.
837TEST_F(PeerConnectionRtpTestUnifiedPlan,
838 DISABLED_RemoteStreamIdChangesUpdatesReceiver) {
Steve Anton3172c032018-05-03 15:30:18 -0700839 auto caller = CreatePeerConnection();
840 auto callee = CreatePeerConnection();
Seth Hampson5b4f0752018-04-02 16:31:36 -0700841
842 const char kStreamId1[] = "stream1";
843 const char kStreamId2[] = "stream2";
Steve Anton0f5400a2018-07-17 14:25:36 -0700844 caller->AddAudioTrack("audio_track1", {kStreamId1});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700845 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700846 EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
847
848 // Change the stream id of the sender in the session description.
849 auto offer = caller->CreateOfferAndSetAsLocal();
850 auto contents = offer->description()->contents();
851 ASSERT_EQ(contents.size(), 1u);
852 ASSERT_EQ(contents[0].media_description()->mutable_streams().size(), 1u);
853 contents[0].media_description()->mutable_streams()[0].set_stream_ids(
854 {kStreamId2});
855
Steve Anton0f5400a2018-07-17 14:25:36 -0700856 // Set the remote description and verify that the stream was updated
857 // properly.
858 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700859 auto receivers = callee->pc()->GetReceivers();
860 ASSERT_EQ(receivers.size(), 1u);
861 ASSERT_EQ(receivers[0]->streams().size(), 1u);
862 EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId2);
863}
864
865// This tests a regression caught by a downstream client, that occured when
866// applying a remote description with a SessionDescription object that
867// contained StreamParams that didn't have ids. Although there were multiple
868// remote audio senders, FindSenderInfo didn't find them as unique, because
869// it looked up by StreamParam.id, which none had. This meant only one
870// AudioRtpReceiver was created, as opposed to one for each remote sender.
Steve Anton3172c032018-05-03 15:30:18 -0700871TEST_F(PeerConnectionRtpTestPlanB,
Seth Hampson5b4f0752018-04-02 16:31:36 -0700872 MultipleRemoteSendersWithoutStreamParamIdAddsMultipleReceivers) {
873 auto caller = CreatePeerConnection();
874 auto callee = CreatePeerConnection();
875
876 const char kStreamId1[] = "stream1";
877 const char kStreamId2[] = "stream2";
878 caller->AddAudioTrack("audio_track1", {kStreamId1});
879 caller->AddAudioTrack("audio_track2", {kStreamId2});
880
881 auto offer = caller->CreateOfferAndSetAsLocal();
882 auto mutable_streams =
883 cricket::GetFirstAudioContentDescription(offer->description())
884 ->mutable_streams();
885 ASSERT_EQ(mutable_streams.size(), 2u);
886 // Clear the IDs in the StreamParams.
887 mutable_streams[0].id.clear();
888 mutable_streams[1].id.clear();
889 ASSERT_TRUE(
890 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
891
892 auto receivers = callee->pc()->GetReceivers();
893 ASSERT_EQ(receivers.size(), 2u);
894 ASSERT_EQ(receivers[0]->streams().size(), 1u);
895 EXPECT_EQ(kStreamId1, receivers[0]->streams()[0]->id());
896 ASSERT_EQ(receivers[1]->streams().size(), 1u);
897 EXPECT_EQ(kStreamId2, receivers[1]->streams()[0]->id());
898}
899
Henrik Boström31638672017-11-23 17:48:32 +0100900// Tests for the legacy SetRemoteDescription() function signature.
Henrik Boström31638672017-11-23 17:48:32 +0100901
902// Sanity test making sure the callback is invoked.
Steve Anton3172c032018-05-03 15:30:18 -0700903TEST_P(PeerConnectionRtpTest, LegacyObserverOnSuccess) {
Henrik Boström31638672017-11-23 17:48:32 +0100904 auto caller = CreatePeerConnection();
905 auto callee = CreatePeerConnection();
906
907 std::string error;
908 ASSERT_TRUE(
909 callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal(), &error));
910}
911
912// Verifies legacy behavior: The observer is not called if if the peer
913// connection is destroyed because the asynchronous callback is executed in the
914// peer connection's message handler.
Steve Anton3172c032018-05-03 15:30:18 -0700915TEST_P(PeerConnectionRtpTest,
916 LegacyObserverNotCalledIfPeerConnectionDereferenced) {
Henrik Boström31638672017-11-23 17:48:32 +0100917 auto caller = CreatePeerConnection();
918 auto callee = CreatePeerConnection();
919
920 rtc::scoped_refptr<webrtc::MockSetSessionDescriptionObserver> observer =
Tommi87f70902021-04-27 14:43:08 +0200921 rtc::make_ref_counted<webrtc::MockSetSessionDescriptionObserver>();
Henrik Boström31638672017-11-23 17:48:32 +0100922
923 auto offer = caller->CreateOfferAndSetAsLocal();
924 callee->pc()->SetRemoteDescription(observer, offer.release());
925 callee = nullptr;
926 rtc::Thread::Current()->ProcessMessages(0);
927 EXPECT_FALSE(observer->called());
928}
929
Steve Antonf9381f02017-12-14 10:23:57 -0800930// RtpTransceiver Tests.
Steve Anton9158ef62017-11-27 13:01:52 -0800931
932// Test that by default there are no transceivers with Unified Plan.
Steve Anton3172c032018-05-03 15:30:18 -0700933TEST_F(PeerConnectionRtpTestUnifiedPlan, PeerConnectionHasNoTransceivers) {
934 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -0800935 EXPECT_THAT(caller->pc()->GetTransceivers(), ElementsAre());
936}
937
938// Test that a transceiver created with the audio kind has the correct initial
939// properties.
Steve Anton3172c032018-05-03 15:30:18 -0700940TEST_F(PeerConnectionRtpTestUnifiedPlan,
941 AddTransceiverHasCorrectInitProperties) {
942 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -0800943
944 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200945 EXPECT_EQ(absl::nullopt, transceiver->mid());
Steve Anton9158ef62017-11-27 13:01:52 -0800946 EXPECT_FALSE(transceiver->stopped());
947 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200948 EXPECT_EQ(absl::nullopt, transceiver->current_direction());
Steve Anton9158ef62017-11-27 13:01:52 -0800949}
950
951// Test that adding a transceiver with the audio kind creates an audio sender
952// and audio receiver with the receiver having a live audio track.
Steve Anton3172c032018-05-03 15:30:18 -0700953TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton9158ef62017-11-27 13:01:52 -0800954 AddAudioTransceiverCreatesAudioSenderAndReceiver) {
Steve Anton3172c032018-05-03 15:30:18 -0700955 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -0800956
957 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Steve Anton69470252018-02-09 11:43:08 -0800958 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->media_type());
Steve Anton9158ef62017-11-27 13:01:52 -0800959
960 ASSERT_TRUE(transceiver->sender());
961 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->sender()->media_type());
962
963 ASSERT_TRUE(transceiver->receiver());
964 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->receiver()->media_type());
965
966 auto track = transceiver->receiver()->track();
967 ASSERT_TRUE(track);
968 EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, track->kind());
969 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
970}
971
972// Test that adding a transceiver with the video kind creates an video sender
973// and video receiver with the receiver having a live video track.
Steve Anton3172c032018-05-03 15:30:18 -0700974TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton9158ef62017-11-27 13:01:52 -0800975 AddAudioTransceiverCreatesVideoSenderAndReceiver) {
Steve Anton3172c032018-05-03 15:30:18 -0700976 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -0800977
978 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
Steve Anton69470252018-02-09 11:43:08 -0800979 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
Steve Anton9158ef62017-11-27 13:01:52 -0800980
981 ASSERT_TRUE(transceiver->sender());
982 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->sender()->media_type());
983
984 ASSERT_TRUE(transceiver->receiver());
985 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->receiver()->media_type());
986
987 auto track = transceiver->receiver()->track();
988 ASSERT_TRUE(track);
989 EXPECT_EQ(MediaStreamTrackInterface::kVideoKind, track->kind());
990 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
991}
992
993// Test that after a call to AddTransceiver, the transceiver shows in
994// GetTransceivers(), the transceiver's sender shows in GetSenders(), and the
995// transceiver's receiver shows in GetReceivers().
Steve Anton3172c032018-05-03 15:30:18 -0700996TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverShowsInLists) {
997 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -0800998
999 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1000 EXPECT_EQ(
1001 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>{transceiver},
1002 caller->pc()->GetTransceivers());
1003 EXPECT_EQ(
1004 std::vector<rtc::scoped_refptr<RtpSenderInterface>>{
1005 transceiver->sender()},
1006 caller->pc()->GetSenders());
1007 EXPECT_EQ(
1008 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
1009 transceiver->receiver()},
1010 caller->pc()->GetReceivers());
1011}
1012
1013// Test that the direction passed in through the AddTransceiver init parameter
1014// is set in the returned transceiver.
Steve Anton3172c032018-05-03 15:30:18 -07001015TEST_F(PeerConnectionRtpTestUnifiedPlan,
1016 AddTransceiverWithDirectionIsReflected) {
1017 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -08001018
1019 RtpTransceiverInit init;
1020 init.direction = RtpTransceiverDirection::kSendOnly;
1021 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1022 EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
1023}
1024
Steve Anton9158ef62017-11-27 13:01:52 -08001025// Test that calling AddTransceiver with a track creates a transceiver which has
1026// its sender's track set to the passed-in track.
Steve Anton3172c032018-05-03 15:30:18 -07001027TEST_F(PeerConnectionRtpTestUnifiedPlan,
1028 AddTransceiverWithTrackCreatesSenderWithTrack) {
1029 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -08001030
1031 auto audio_track = caller->CreateAudioTrack("audio track");
1032 auto transceiver = caller->AddTransceiver(audio_track);
1033
1034 auto sender = transceiver->sender();
1035 ASSERT_TRUE(sender->track());
1036 EXPECT_EQ(audio_track, sender->track());
1037
1038 auto receiver = transceiver->receiver();
1039 ASSERT_TRUE(receiver->track());
1040 EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, receiver->track()->kind());
1041 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive,
1042 receiver->track()->state());
1043}
1044
1045// Test that calling AddTransceiver twice with the same track creates distinct
1046// transceivers, senders with the same track.
Steve Anton3172c032018-05-03 15:30:18 -07001047TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton9158ef62017-11-27 13:01:52 -08001048 AddTransceiverTwiceWithSameTrackCreatesMultipleTransceivers) {
Steve Anton3172c032018-05-03 15:30:18 -07001049 auto caller = CreatePeerConnection();
Steve Anton9158ef62017-11-27 13:01:52 -08001050
1051 auto audio_track = caller->CreateAudioTrack("audio track");
1052
1053 auto transceiver1 = caller->AddTransceiver(audio_track);
1054 auto transceiver2 = caller->AddTransceiver(audio_track);
1055
1056 EXPECT_NE(transceiver1, transceiver2);
1057
1058 auto sender1 = transceiver1->sender();
1059 auto sender2 = transceiver2->sender();
1060 EXPECT_NE(sender1, sender2);
1061 EXPECT_EQ(audio_track, sender1->track());
1062 EXPECT_EQ(audio_track, sender2->track());
1063
1064 EXPECT_THAT(caller->pc()->GetTransceivers(),
1065 UnorderedElementsAre(transceiver1, transceiver2));
1066 EXPECT_THAT(caller->pc()->GetSenders(),
1067 UnorderedElementsAre(sender1, sender2));
1068}
1069
Steve Anton3fe1b152017-12-12 10:20:08 -08001070// RtpTransceiver error handling tests.
1071
Steve Anton3172c032018-05-03 15:30:18 -07001072TEST_F(PeerConnectionRtpTestUnifiedPlan,
1073 AddTransceiverWithInvalidKindReturnsError) {
1074 auto caller = CreatePeerConnection();
Steve Anton3fe1b152017-12-12 10:20:08 -08001075
1076 auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_DATA);
1077 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
1078}
1079
Steve Anton3172c032018-05-03 15:30:18 -07001080TEST_F(PeerConnectionRtpTestUnifiedPlan,
1081 CanClosePeerConnectionWithoutCrashing) {
1082 auto caller = CreatePeerConnection();
Steve Anton3fe1b152017-12-12 10:20:08 -08001083
1084 caller->pc()->Close();
1085}
1086
Steve Antonf9381f02017-12-14 10:23:57 -08001087// Unified Plan AddTrack tests.
1088
Steve Antonf9381f02017-12-14 10:23:57 -08001089// Test that adding an audio track creates a new audio RtpSender with the given
1090// track.
Steve Anton3172c032018-05-03 15:30:18 -07001091TEST_F(PeerConnectionRtpTestUnifiedPlan, AddAudioTrackCreatesAudioSender) {
1092 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001093
1094 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -08001095 auto sender = caller->AddTrack(audio_track);
Steve Antonf9381f02017-12-14 10:23:57 -08001096 ASSERT_TRUE(sender);
1097
1098 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, sender->media_type());
1099 EXPECT_EQ(audio_track, sender->track());
1100}
1101
1102// Test that adding a video track creates a new video RtpSender with the given
1103// track.
Steve Anton3172c032018-05-03 15:30:18 -07001104TEST_F(PeerConnectionRtpTestUnifiedPlan, AddVideoTrackCreatesVideoSender) {
1105 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001106
1107 auto video_track = caller->CreateVideoTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -08001108 auto sender = caller->AddTrack(video_track);
Steve Antonf9381f02017-12-14 10:23:57 -08001109 ASSERT_TRUE(sender);
1110
1111 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
1112 EXPECT_EQ(video_track, sender->track());
1113}
1114
1115// Test that adding a track to a new PeerConnection creates an RtpTransceiver
1116// with the sender that AddTrack returns and in the sendrecv direction.
Steve Anton3172c032018-05-03 15:30:18 -07001117TEST_F(PeerConnectionRtpTestUnifiedPlan, AddFirstTrackCreatesTransceiver) {
1118 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001119
1120 auto sender = caller->AddAudioTrack("a");
1121 ASSERT_TRUE(sender);
1122
1123 auto transceivers = caller->pc()->GetTransceivers();
1124 ASSERT_EQ(1u, transceivers.size());
1125 EXPECT_EQ(sender, transceivers[0]->sender());
1126 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceivers[0]->direction());
1127}
1128
1129// Test that if a transceiver of the same type but no track had been added to
1130// the PeerConnection and later a call to AddTrack is made, the resulting sender
1131// is the transceiver's sender and the sender's track is the newly-added track.
Steve Anton3172c032018-05-03 15:30:18 -07001132TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiver) {
1133 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001134
1135 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1136 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -08001137 auto sender = caller->AddTrack(audio_track);
Steve Antonf9381f02017-12-14 10:23:57 -08001138 ASSERT_TRUE(sender);
1139
1140 auto transceivers = caller->pc()->GetTransceivers();
1141 ASSERT_EQ(1u, transceivers.size());
1142 EXPECT_EQ(transceiver, transceivers[0]);
1143 EXPECT_EQ(sender, transceiver->sender());
1144 EXPECT_EQ(audio_track, sender->track());
1145}
1146
1147// Test that adding two tracks to a new PeerConnection creates two
1148// RtpTransceivers in the same order.
Steve Anton3172c032018-05-03 15:30:18 -07001149TEST_F(PeerConnectionRtpTestUnifiedPlan, TwoAddTrackCreatesTwoTransceivers) {
1150 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001151
1152 auto sender1 = caller->AddAudioTrack("a");
1153 auto sender2 = caller->AddVideoTrack("v");
1154 ASSERT_TRUE(sender2);
1155
1156 auto transceivers = caller->pc()->GetTransceivers();
1157 ASSERT_EQ(2u, transceivers.size());
1158 EXPECT_EQ(sender1, transceivers[0]->sender());
1159 EXPECT_EQ(sender2, transceivers[1]->sender());
1160}
1161
1162// Test that if there are multiple transceivers with no sending track then a
1163// later call to AddTrack will use the one of the same type as the newly-added
1164// track.
Steve Anton3172c032018-05-03 15:30:18 -07001165TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiverOfType) {
1166 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001167
1168 auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1169 auto video_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
1170 auto sender = caller->AddVideoTrack("v");
1171
1172 ASSERT_EQ(2u, caller->pc()->GetTransceivers().size());
1173 EXPECT_NE(sender, audio_transceiver->sender());
1174 EXPECT_EQ(sender, video_transceiver->sender());
1175}
1176
1177// Test that if the only transceivers that do not have a sending track have a
1178// different type from the added track, then AddTrack will create a new
1179// transceiver for the track.
Steve Anton3172c032018-05-03 15:30:18 -07001180TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001181 AddTrackDoesNotReuseTransceiverOfWrongType) {
Steve Anton3172c032018-05-03 15:30:18 -07001182 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001183
1184 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1185 auto sender = caller->AddVideoTrack("v");
1186
1187 auto transceivers = caller->pc()->GetTransceivers();
1188 ASSERT_EQ(2u, transceivers.size());
1189 EXPECT_NE(sender, transceivers[0]->sender());
1190 EXPECT_EQ(sender, transceivers[1]->sender());
1191}
1192
1193// Test that the first available transceiver is reused by AddTrack when multiple
1194// are available.
Steve Anton3172c032018-05-03 15:30:18 -07001195TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001196 AddTrackReusesFirstMatchingTransceiver) {
Steve Anton3172c032018-05-03 15:30:18 -07001197 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001198
1199 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1200 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1201 auto sender = caller->AddAudioTrack("a");
1202
1203 auto transceivers = caller->pc()->GetTransceivers();
1204 ASSERT_EQ(2u, transceivers.size());
1205 EXPECT_EQ(sender, transceivers[0]->sender());
1206 EXPECT_NE(sender, transceivers[1]->sender());
1207}
1208
1209// Test that a call to AddTrack that reuses a transceiver will change the
1210// direction from inactive to sendonly.
Steve Anton3172c032018-05-03 15:30:18 -07001211TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001212 AddTrackChangesDirectionFromInactiveToSendOnly) {
Steve Anton3172c032018-05-03 15:30:18 -07001213 auto caller = CreatePeerConnection();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001214 auto callee = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001215
1216 RtpTransceiverInit init;
1217 init.direction = RtpTransceiverDirection::kInactive;
1218 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
Henrik Boströme574a312020-08-25 10:20:11 +02001219 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1220 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001221
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001222 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02001223 caller->observer()->clear_legacy_renegotiation_needed();
1224 caller->observer()->clear_latest_negotiation_needed_event();
Steve Antonf9381f02017-12-14 10:23:57 -08001225 ASSERT_TRUE(caller->AddAudioTrack("a"));
Henrik Boströme574a312020-08-25 10:20:11 +02001226 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1227 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001228
1229 EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
1230}
1231
1232// Test that a call to AddTrack that reuses a transceiver will change the
1233// direction from recvonly to sendrecv.
Steve Anton3172c032018-05-03 15:30:18 -07001234TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001235 AddTrackChangesDirectionFromRecvOnlyToSendRecv) {
Steve Anton3172c032018-05-03 15:30:18 -07001236 auto caller = CreatePeerConnection();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001237 auto callee = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001238
1239 RtpTransceiverInit init;
1240 init.direction = RtpTransceiverDirection::kRecvOnly;
1241 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
Henrik Boströme574a312020-08-25 10:20:11 +02001242 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1243 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001244
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001245 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02001246 caller->observer()->clear_legacy_renegotiation_needed();
1247 caller->observer()->clear_latest_negotiation_needed_event();
Steve Antonf9381f02017-12-14 10:23:57 -08001248 ASSERT_TRUE(caller->AddAudioTrack("a"));
Henrik Boströme574a312020-08-25 10:20:11 +02001249 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1250 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001251
1252 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
1253}
1254
Steve Anton3172c032018-05-03 15:30:18 -07001255TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackCreatesSenderWithTrackId) {
Steve Anton02ee47c2018-01-10 16:26:06 -08001256 const std::string kTrackId = "audio_track";
1257
Steve Anton3172c032018-05-03 15:30:18 -07001258 auto caller = CreatePeerConnection();
Steve Anton02ee47c2018-01-10 16:26:06 -08001259
1260 auto audio_track = caller->CreateAudioTrack(kTrackId);
1261 auto sender = caller->AddTrack(audio_track);
1262
1263 EXPECT_EQ(kTrackId, sender->id());
1264}
1265
Steve Antonf9381f02017-12-14 10:23:57 -08001266// Unified Plan AddTrack error handling.
1267
Steve Anton3172c032018-05-03 15:30:18 -07001268TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfClosed) {
1269 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001270
1271 auto audio_track = caller->CreateAudioTrack("a");
1272 caller->pc()->Close();
1273
Henrik Boströme574a312020-08-25 10:20:11 +02001274 caller->observer()->clear_legacy_renegotiation_needed();
1275 caller->observer()->clear_latest_negotiation_needed_event();
Yves Gerey665174f2018-06-19 15:03:05 +02001276 auto result = caller->pc()->AddTrack(audio_track, std::vector<std::string>());
Steve Anton2d6c76a2018-01-05 17:10:52 -08001277 EXPECT_EQ(RTCErrorType::INVALID_STATE, result.error().type());
Henrik Boströme574a312020-08-25 10:20:11 +02001278 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1279 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001280}
1281
Steve Anton3172c032018-05-03 15:30:18 -07001282TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfTrackAlreadyHasSender) {
1283 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001284
1285 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -08001286 ASSERT_TRUE(caller->AddTrack(audio_track));
Steve Antonf9381f02017-12-14 10:23:57 -08001287
Henrik Boströme574a312020-08-25 10:20:11 +02001288 caller->observer()->clear_legacy_renegotiation_needed();
1289 caller->observer()->clear_latest_negotiation_needed_event();
Yves Gerey665174f2018-06-19 15:03:05 +02001290 auto result = caller->pc()->AddTrack(audio_track, std::vector<std::string>());
Steve Anton2d6c76a2018-01-05 17:10:52 -08001291 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Henrik Boströme574a312020-08-25 10:20:11 +02001292 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1293 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001294}
1295
1296// Unified Plan RemoveTrack tests.
1297
1298// Test that calling RemoveTrack on a sender with a previously-added track
1299// clears the sender's track.
Steve Anton3172c032018-05-03 15:30:18 -07001300TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackClearsSenderTrack) {
1301 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001302
1303 auto sender = caller->AddAudioTrack("a");
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001304 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Steve Antonf9381f02017-12-14 10:23:57 -08001305
1306 EXPECT_FALSE(sender->track());
1307}
1308
1309// Test that calling RemoveTrack on a sender where the transceiver is configured
1310// in the sendrecv direction changes the transceiver's direction to recvonly.
Steve Anton3172c032018-05-03 15:30:18 -07001311TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001312 RemoveTrackChangesDirectionFromSendRecvToRecvOnly) {
Steve Anton3172c032018-05-03 15:30:18 -07001313 auto caller = CreatePeerConnection();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001314 auto callee = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001315
1316 RtpTransceiverInit init;
1317 init.direction = RtpTransceiverDirection::kSendRecv;
1318 auto transceiver =
1319 caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
Henrik Boströme574a312020-08-25 10:20:11 +02001320 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1321 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001322
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001323 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02001324 caller->observer()->clear_legacy_renegotiation_needed();
1325 caller->observer()->clear_latest_negotiation_needed_event();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001326
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001327 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(transceiver->sender()).ok());
Henrik Boströme574a312020-08-25 10:20:11 +02001328 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1329 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001330
1331 EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceiver->direction());
Steve Antonf9381f02017-12-14 10:23:57 -08001332}
1333
1334// Test that calling RemoveTrack on a sender where the transceiver is configured
1335// in the sendonly direction changes the transceiver's direction to inactive.
Steve Anton3172c032018-05-03 15:30:18 -07001336TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001337 RemoveTrackChangesDirectionFromSendOnlyToInactive) {
Steve Anton3172c032018-05-03 15:30:18 -07001338 auto caller = CreatePeerConnection();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001339 auto callee = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001340
1341 RtpTransceiverInit init;
1342 init.direction = RtpTransceiverDirection::kSendOnly;
1343 auto transceiver =
1344 caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
Henrik Boströme574a312020-08-25 10:20:11 +02001345 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1346 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001347
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001348 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02001349 caller->observer()->clear_legacy_renegotiation_needed();
1350 caller->observer()->clear_latest_negotiation_needed_event();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001351
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001352 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(transceiver->sender()).ok());
Henrik Boströme574a312020-08-25 10:20:11 +02001353 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1354 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001355
1356 EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver->direction());
1357}
1358
1359// Test that calling RemoveTrack with a sender that has a null track results in
1360// no change in state.
Steve Anton3172c032018-05-03 15:30:18 -07001361TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackWithNullSenderTrackIsNoOp) {
1362 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001363
1364 auto sender = caller->AddAudioTrack("a");
1365 auto transceiver = caller->pc()->GetTransceivers()[0];
1366 ASSERT_TRUE(sender->SetTrack(nullptr));
1367
Henrik Boströme574a312020-08-25 10:20:11 +02001368 caller->observer()->clear_legacy_renegotiation_needed();
1369 caller->observer()->clear_latest_negotiation_needed_event();
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001370 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Henrik Boströme574a312020-08-25 10:20:11 +02001371 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1372 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001373
1374 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
1375}
1376
1377// Unified Plan RemoveTrack error handling.
1378
Steve Anton3172c032018-05-03 15:30:18 -07001379TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackErrorIfClosed) {
1380 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001381
1382 auto sender = caller->AddAudioTrack("a");
1383 caller->pc()->Close();
1384
Henrik Boströme574a312020-08-25 10:20:11 +02001385 caller->observer()->clear_legacy_renegotiation_needed();
1386 caller->observer()->clear_latest_negotiation_needed_event();
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001387 EXPECT_FALSE(caller->pc()->RemoveTrackOrError(sender).ok());
Henrik Boströme574a312020-08-25 10:20:11 +02001388 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1389 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001390}
1391
Steve Anton3172c032018-05-03 15:30:18 -07001392TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Antonf9381f02017-12-14 10:23:57 -08001393 RemoveTrackNoErrorIfTrackAlreadyRemoved) {
Steve Anton3172c032018-05-03 15:30:18 -07001394 auto caller = CreatePeerConnection();
Steve Antonf9381f02017-12-14 10:23:57 -08001395
1396 auto sender = caller->AddAudioTrack("a");
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001397 ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Steve Antonf9381f02017-12-14 10:23:57 -08001398
Henrik Boströme574a312020-08-25 10:20:11 +02001399 caller->observer()->clear_legacy_renegotiation_needed();
1400 caller->observer()->clear_latest_negotiation_needed_event();
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001401 EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
Henrik Boströme574a312020-08-25 10:20:11 +02001402 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1403 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Antonf9381f02017-12-14 10:23:57 -08001404}
1405
Steve Anton60b6c1d2018-06-13 11:32:27 -07001406// Test that setting offers that add/remove/add a track repeatedly without
1407// setting the appropriate answer in between works.
1408// These are regression tests for bugs.webrtc.org/9401
1409TEST_F(PeerConnectionRtpTestUnifiedPlan, AddRemoveAddTrackOffersWorksAudio) {
1410 auto caller = CreatePeerConnection();
1411
1412 auto sender1 = caller->AddAudioTrack("audio1");
1413 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1414
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001415 caller->pc()->RemoveTrackOrError(sender1);
Steve Anton60b6c1d2018-06-13 11:32:27 -07001416 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1417
1418 // This will re-use the transceiver created by the first AddTrack.
1419 auto sender2 = caller->AddAudioTrack("audio2");
1420 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1421
1422 EXPECT_EQ(1u, caller->pc()->GetTransceivers().size());
1423 EXPECT_EQ(sender1, sender2);
1424}
1425TEST_F(PeerConnectionRtpTestUnifiedPlan, AddRemoveAddTrackOffersWorksVideo) {
1426 auto caller = CreatePeerConnection();
1427
1428 auto sender1 = caller->AddVideoTrack("video1");
1429 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1430
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001431 caller->pc()->RemoveTrackOrError(sender1);
Steve Anton60b6c1d2018-06-13 11:32:27 -07001432 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1433
1434 // This will re-use the transceiver created by the first AddTrack.
1435 auto sender2 = caller->AddVideoTrack("video2");
1436 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1437
1438 EXPECT_EQ(1u, caller->pc()->GetTransceivers().size());
1439 EXPECT_EQ(sender1, sender2);
1440}
1441
Steve Anton07563732018-06-26 11:13:50 -07001442// Test that CreateOffer succeeds if two tracks with the same label are added.
1443TEST_F(PeerConnectionRtpTestUnifiedPlan, CreateOfferSameTrackLabel) {
1444 auto caller = CreatePeerConnection();
1445
1446 auto audio_sender = caller->AddAudioTrack("track", {});
1447 auto video_sender = caller->AddVideoTrack("track", {});
1448
1449 EXPECT_TRUE(caller->CreateOffer());
1450
1451 EXPECT_EQ(audio_sender->track()->id(), video_sender->track()->id());
1452 EXPECT_NE(audio_sender->id(), video_sender->id());
1453}
1454
1455// Test that CreateAnswer succeeds if two tracks with the same label are added.
1456TEST_F(PeerConnectionRtpTestUnifiedPlan, CreateAnswerSameTrackLabel) {
1457 auto caller = CreatePeerConnection();
1458 auto callee = CreatePeerConnection();
1459
1460 RtpTransceiverInit recvonly;
1461 recvonly.direction = RtpTransceiverDirection::kRecvOnly;
1462 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, recvonly);
1463 caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, recvonly);
1464
1465 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1466
1467 auto audio_sender = callee->AddAudioTrack("track", {});
1468 auto video_sender = callee->AddVideoTrack("track", {});
1469
1470 EXPECT_TRUE(callee->CreateAnswer());
1471
1472 EXPECT_EQ(audio_sender->track()->id(), video_sender->track()->id());
1473 EXPECT_NE(audio_sender->id(), video_sender->id());
1474}
1475
1476// Test that calling AddTrack, RemoveTrack and AddTrack again creates a second
1477// m= section with a random sender id (different from the first, now rejected,
1478// m= section).
1479TEST_F(PeerConnectionRtpTestUnifiedPlan,
1480 AddRemoveAddTrackGeneratesNewSenderId) {
1481 auto caller = CreatePeerConnection();
1482 auto callee = CreatePeerConnection();
1483
1484 auto track = caller->CreateVideoTrack("video");
1485 auto sender1 = caller->AddTrack(track);
1486 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1487
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001488 caller->pc()->RemoveTrackOrError(sender1);
Steve Anton07563732018-06-26 11:13:50 -07001489 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1490
1491 auto sender2 = caller->AddTrack(track);
1492
1493 EXPECT_NE(sender1, sender2);
1494 EXPECT_NE(sender1->id(), sender2->id());
1495 std::string sender2_id = sender2->id();
1496
1497 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1498
1499 // The sender's ID should not change after negotiation.
1500 EXPECT_EQ(sender2_id, sender2->id());
1501}
1502
Steve Anton52d86772018-02-20 15:48:12 -08001503// Test that OnRenegotiationNeeded is fired if SetDirection is called on an
1504// active RtpTransceiver with a new direction.
Steve Anton3172c032018-05-03 15:30:18 -07001505TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton52d86772018-02-20 15:48:12 -08001506 RenegotiationNeededAfterTransceiverSetDirection) {
Steve Anton3172c032018-05-03 15:30:18 -07001507 auto caller = CreatePeerConnection();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001508 auto callee = CreatePeerConnection();
Henrik Boströme574a312020-08-25 10:20:11 +02001509 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1510 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Anton52d86772018-02-20 15:48:12 -08001511
1512 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Henrik Boströme574a312020-08-25 10:20:11 +02001513 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1514 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Anton52d86772018-02-20 15:48:12 -08001515
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001516 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02001517 caller->observer()->clear_legacy_renegotiation_needed();
1518 caller->observer()->clear_latest_negotiation_needed_event();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001519
Harald Alvestrand6060df52020-08-11 09:54:02 +02001520 transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive);
Henrik Boströme574a312020-08-25 10:20:11 +02001521 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1522 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Steve Anton52d86772018-02-20 15:48:12 -08001523}
1524
1525// Test that OnRenegotiationNeeded is not fired if SetDirection is called on an
1526// active RtpTransceiver with current direction.
Steve Anton3172c032018-05-03 15:30:18 -07001527TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton52d86772018-02-20 15:48:12 -08001528 NoRenegotiationNeededAfterTransceiverSetSameDirection) {
Steve Anton3172c032018-05-03 15:30:18 -07001529 auto caller = CreatePeerConnection();
Steve Anton52d86772018-02-20 15:48:12 -08001530
1531 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1532
Henrik Boströme574a312020-08-25 10:20:11 +02001533 caller->observer()->clear_legacy_renegotiation_needed();
1534 caller->observer()->clear_latest_negotiation_needed_event();
Harald Alvestrand6060df52020-08-11 09:54:02 +02001535 transceiver->SetDirectionWithError(transceiver->direction());
Henrik Boströme574a312020-08-25 10:20:11 +02001536 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1537 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Anton52d86772018-02-20 15:48:12 -08001538}
1539
1540// Test that OnRenegotiationNeeded is not fired if SetDirection is called on a
1541// stopped RtpTransceiver.
Steve Anton3172c032018-05-03 15:30:18 -07001542TEST_F(PeerConnectionRtpTestUnifiedPlan,
Steve Anton52d86772018-02-20 15:48:12 -08001543 NoRenegotiationNeededAfterSetDirectionOnStoppedTransceiver) {
Steve Anton3172c032018-05-03 15:30:18 -07001544 auto caller = CreatePeerConnection();
Steve Anton52d86772018-02-20 15:48:12 -08001545
1546 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02001547 transceiver->StopInternal();
Steve Anton52d86772018-02-20 15:48:12 -08001548
Henrik Boströme574a312020-08-25 10:20:11 +02001549 caller->observer()->clear_legacy_renegotiation_needed();
1550 caller->observer()->clear_latest_negotiation_needed_event();
Harald Alvestrand6060df52020-08-11 09:54:02 +02001551 transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive);
Henrik Boströme574a312020-08-25 10:20:11 +02001552 EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1553 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
Steve Anton52d86772018-02-20 15:48:12 -08001554}
1555
Harald Alvestrand6060df52020-08-11 09:54:02 +02001556// Test that currentDirection returnes "stopped" if the transceiver was stopped.
1557TEST_F(PeerConnectionRtpTestUnifiedPlan,
1558 CheckStoppedCurrentDirectionOnStoppedTransceiver) {
1559 auto caller = CreatePeerConnection();
1560
1561 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1562 transceiver->StopInternal();
1563
1564 EXPECT_TRUE(transceiver->stopping());
1565 EXPECT_TRUE(transceiver->stopped());
1566 EXPECT_EQ(RtpTransceiverDirection::kStopped,
1567 transceiver->current_direction());
1568}
1569
1570// Test that InvalidState is thrown on a stopping transceiver.
1571TEST_F(PeerConnectionRtpTestUnifiedPlan,
1572 CheckForInvalidStateOnStoppingTransceiver) {
1573 auto caller = CreatePeerConnection();
1574
1575 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1576 transceiver->StopStandard();
1577
1578 EXPECT_TRUE(transceiver->stopping());
1579 EXPECT_FALSE(transceiver->stopped());
1580 EXPECT_EQ(
1581 RTCErrorType::INVALID_STATE,
1582 transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
1583 .type());
1584}
1585
1586// Test that InvalidState is thrown on a stopped transceiver.
1587TEST_F(PeerConnectionRtpTestUnifiedPlan,
1588 CheckForInvalidStateOnStoppedTransceiver) {
1589 auto caller = CreatePeerConnection();
1590
1591 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1592 transceiver->StopInternal();
1593
1594 EXPECT_TRUE(transceiver->stopping());
1595 EXPECT_TRUE(transceiver->stopped());
1596 EXPECT_EQ(
1597 RTCErrorType::INVALID_STATE,
1598 transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
1599 .type());
1600}
1601
1602// Test that TypeError is thrown if the direction is set to "stopped".
1603TEST_F(PeerConnectionRtpTestUnifiedPlan,
1604 CheckForTypeErrorForStoppedOnTransceiver) {
1605 auto caller = CreatePeerConnection();
1606
1607 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1608 EXPECT_EQ(
1609 RTCErrorType::INVALID_PARAMETER,
1610 transceiver->SetDirectionWithError(RtpTransceiverDirection::kStopped)
1611 .type());
1612}
1613
Harald Alvestrand198cd732020-09-16 12:41:23 +00001614// Test that you can do createOffer/setLocalDescription with a stopped
1615// media section.
1616TEST_F(PeerConnectionRtpTestUnifiedPlan,
1617 SetLocalDescriptionWithStoppedMediaSection) {
1618 auto caller = CreatePeerConnection();
1619 auto callee = CreatePeerConnection();
1620 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1621 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1622 callee->pc()->GetTransceivers()[0]->StopStandard();
1623 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1624 EXPECT_EQ(RtpTransceiverDirection::kStopped,
1625 transceiver->current_direction());
1626 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1627}
1628
Harald Alvestrand936f1af2020-09-22 07:41:50 +00001629TEST_F(PeerConnectionRtpTestUnifiedPlan,
1630 StopAndNegotiateCausesTransceiverToDisappear) {
1631 auto caller = CreatePeerConnection();
1632 auto callee = CreatePeerConnection();
1633 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1634 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1635 callee->pc()->GetTransceivers()[0]->StopStandard();
1636 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1637 EXPECT_EQ(RtpTransceiverDirection::kStopped,
1638 transceiver->current_direction());
1639 EXPECT_EQ(0U, caller->pc()->GetTransceivers().size());
1640 EXPECT_EQ(0U, callee->pc()->GetTransceivers().size());
1641 EXPECT_EQ(0U, caller->pc()->GetSenders().size());
1642 EXPECT_EQ(0U, callee->pc()->GetSenders().size());
1643 EXPECT_EQ(0U, caller->pc()->GetReceivers().size());
1644 EXPECT_EQ(0U, callee->pc()->GetReceivers().size());
1645}
1646
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +00001647TEST_F(PeerConnectionRtpTestUnifiedPlan,
1648 SetLocalDescriptionWorksAfterRepeatedAddRemove) {
1649 auto caller = CreatePeerConnection();
1650 auto callee = CreatePeerConnection();
1651 auto video_track = caller->CreateVideoTrack("v");
1652 auto track = caller->CreateAudioTrack("a");
1653 caller->AddTransceiver(video_track);
1654 auto transceiver = caller->AddTransceiver(track);
1655 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001656 caller->pc()->RemoveTrackOrError(transceiver->sender());
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +00001657 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1658 caller->AddTrack(track);
1659 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001660 caller->pc()->RemoveTrackOrError(transceiver->sender());
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +00001661 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1662}
1663
1664// This is a repro of Chromium bug https://crbug.com/1134686
1665TEST_F(PeerConnectionRtpTestUnifiedPlan,
1666 SetLocalDescriptionWorksAfterRepeatedAddRemoveWithRemoteReject) {
1667 auto caller = CreatePeerConnection();
1668 auto callee = CreatePeerConnection();
1669 auto video_track = caller->CreateVideoTrack("v");
1670 auto track = caller->CreateAudioTrack("a");
1671 caller->AddTransceiver(video_track);
1672 auto transceiver = caller->AddTransceiver(track);
1673 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001674 caller->pc()->RemoveTrackOrError(transceiver->sender());
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +00001675 ExchangeOfferAnswerWhereRemoteStopsTransceiver(caller.get(), callee.get(), 1);
1676 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1677 caller->AddTrack(track);
1678 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Harald Alvestrand93dd7632022-01-19 12:28:45 +00001679 caller->pc()->RemoveTrackOrError(transceiver->sender());
Harald Alvestrand09bd9ba2020-10-09 08:13:30 +00001680 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1681}
1682
Florent Castelli892acf02018-10-01 22:47:20 +02001683// Test that AddTransceiver fails if trying to use unimplemented RTP encoding
1684// parameters with the send_encodings parameters.
1685TEST_F(PeerConnectionRtpTestUnifiedPlan,
1686 CheckForUnsupportedEncodingParameters) {
1687 auto caller = CreatePeerConnection();
1688
1689 RtpTransceiverInit init;
1690 init.send_encodings.emplace_back();
1691
1692 auto default_send_encodings = init.send_encodings;
1693
Henrik Grunelle1301a82018-12-13 12:13:22 +00001694 // Unimplemented RtpParameters: ssrc, codec_payload_type, fec, rtx, dtx,
Amit Hilbuchaa584152019-02-06 17:09:52 -08001695 // ptime, scale_framerate_down_by, dependency_rids.
Florent Castelli892acf02018-10-01 22:47:20 +02001696 init.send_encodings[0].ssrc = 1;
1697 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
1698 caller->pc()
1699 ->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init)
1700 .error()
1701 .type());
1702 init.send_encodings = default_send_encodings;
Florent Castelli892acf02018-10-01 22:47:20 +02001703}
1704
Florent Castellic1a0bcb2019-01-29 14:26:48 +01001705// Test that AddTransceiver fails if trying to use invalid RTP encoding
1706// parameters with the send_encodings parameters.
1707TEST_F(PeerConnectionRtpTestUnifiedPlan, CheckForInvalidEncodingParameters) {
1708 auto caller = CreatePeerConnection();
1709
1710 RtpTransceiverInit init;
1711 init.send_encodings.emplace_back();
1712
1713 auto default_send_encodings = init.send_encodings;
1714
1715 init.send_encodings[0].scale_resolution_down_by = 0.5;
1716 EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1717 caller->pc()
1718 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1719 .error()
1720 .type());
1721 init.send_encodings = default_send_encodings;
1722
1723 init.send_encodings[0].bitrate_priority = 0;
1724 EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1725 caller->pc()
1726 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1727 .error()
1728 .type());
1729 init.send_encodings = default_send_encodings;
1730
1731 init.send_encodings[0].min_bitrate_bps = 200000;
1732 init.send_encodings[0].max_bitrate_bps = 100000;
1733 EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1734 caller->pc()
1735 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1736 .error()
1737 .type());
1738 init.send_encodings = default_send_encodings;
1739
1740 init.send_encodings[0].num_temporal_layers = 0;
1741 EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1742 caller->pc()
1743 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1744 .error()
1745 .type());
1746 init.send_encodings = default_send_encodings;
1747
1748 init.send_encodings[0].num_temporal_layers = 5;
1749 EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1750 caller->pc()
1751 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1752 .error()
1753 .type());
1754 init.send_encodings = default_send_encodings;
1755}
1756
Florent Castelli892acf02018-10-01 22:47:20 +02001757// Test that AddTransceiver transfers the send_encodings to the sender and they
1758// are retained after SetLocalDescription().
1759TEST_F(PeerConnectionRtpTestUnifiedPlan, SendEncodingsPassedToSender) {
1760 auto caller = CreatePeerConnection();
1761
1762 RtpTransceiverInit init;
1763 init.send_encodings.emplace_back();
1764 init.send_encodings[0].active = false;
1765 init.send_encodings[0].max_bitrate_bps = 180000;
1766
1767 auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1768 ASSERT_TRUE(result.ok());
1769
1770 auto init_send_encodings = result.value()->sender()->init_send_encodings();
1771 EXPECT_FALSE(init_send_encodings[0].active);
1772 EXPECT_EQ(init_send_encodings[0].max_bitrate_bps, 180000);
1773
1774 auto parameters = result.value()->sender()->GetParameters();
1775 EXPECT_FALSE(parameters.encodings[0].active);
1776 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps, 180000);
1777
1778 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1779
1780 parameters = result.value()->sender()->GetParameters();
1781 EXPECT_FALSE(parameters.encodings[0].active);
1782 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps, 180000);
1783}
1784
Steve Antone831b8c2018-02-01 12:22:16 -08001785// Test MSID signaling between Unified Plan and Plan B endpoints. There are two
1786// options for this kind of signaling: media section based (a=msid) and ssrc
1787// based (a=ssrc MSID). While JSEP only specifies media section MSID signaling,
1788// we want to ensure compatibility with older Plan B endpoints that might expect
1789// ssrc based MSID signaling. Thus we test here that Unified Plan offers both
1790// types but answers with the same type as the offer.
1791
Steve Anton3172c032018-05-03 15:30:18 -07001792class PeerConnectionMsidSignalingTest
1793 : public PeerConnectionRtpTestUnifiedPlan {};
Steve Antone831b8c2018-02-01 12:22:16 -08001794
1795TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanTalkingToOurself) {
1796 auto caller = CreatePeerConnectionWithUnifiedPlan();
1797 caller->AddAudioTrack("caller_audio");
1798 auto callee = CreatePeerConnectionWithUnifiedPlan();
1799 callee->AddAudioTrack("callee_audio");
1800
1801 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1802
1803 // Offer should have had both a=msid and a=ssrc MSID lines.
1804 auto* offer = callee->pc()->remote_description();
1805 EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1806 cricket::kMsidSignalingSsrcAttribute),
1807 offer->description()->msid_signaling());
1808
1809 // Answer should have had only a=msid lines.
1810 auto* answer = caller->pc()->remote_description();
1811 EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1812 answer->description()->msid_signaling());
Harald Alvestrand5dbb5862018-02-13 23:48:00 +01001813 // Check that this is counted correctly
Ying Wangef3998f2019-12-09 13:06:53 +01001814 EXPECT_METRIC_THAT(
1815 metrics::Samples("WebRTC.PeerConnection.SdpSemanticNegotiated"),
1816 ElementsAre(Pair(kSdpSemanticNegotiatedUnifiedPlan, 2)));
Steve Antone831b8c2018-02-01 12:22:16 -08001817}
1818
1819TEST_F(PeerConnectionMsidSignalingTest, PlanBOfferToUnifiedPlanAnswer) {
1820 auto caller = CreatePeerConnectionWithPlanB();
1821 caller->AddAudioTrack("caller_audio");
1822 auto callee = CreatePeerConnectionWithUnifiedPlan();
1823 callee->AddAudioTrack("callee_audio");
1824
1825 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1826
1827 // Offer should have only a=ssrc MSID lines.
1828 auto* offer = callee->pc()->remote_description();
1829 EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1830 offer->description()->msid_signaling());
1831
1832 // Answer should have only a=ssrc MSID lines to match the offer.
1833 auto* answer = caller->pc()->remote_description();
1834 EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1835 answer->description()->msid_signaling());
1836}
1837
Seth Hampson5b4f0752018-04-02 16:31:36 -07001838// This tests that a Plan B endpoint appropriately sets the remote description
1839// from a Unified Plan offer. When the Unified Plan offer contains a=msid lines
1840// that signal no stream ids or multiple stream ids we expect that the Plan B
1841// endpoint always has exactly one media stream per track.
1842TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanToPlanBAnswer) {
1843 const std::string kStreamId1 = "audio_stream_1";
1844 const std::string kStreamId2 = "audio_stream_2";
1845
1846 auto caller = CreatePeerConnectionWithUnifiedPlan();
1847 caller->AddAudioTrack("caller_audio", {kStreamId1, kStreamId2});
1848 caller->AddVideoTrack("caller_video", {});
1849 auto callee = CreatePeerConnectionWithPlanB();
1850 callee->AddAudioTrack("callee_audio");
1851 caller->AddVideoTrack("callee_video");
1852
1853 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1854
1855 // Offer should have had both a=msid and a=ssrc MSID lines.
1856 auto* offer = callee->pc()->remote_description();
1857 EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1858 cricket::kMsidSignalingSsrcAttribute),
1859 offer->description()->msid_signaling());
1860
1861 // Callee should always have 1 stream for all of it's receivers.
1862 const auto& track_events = callee->observer()->add_track_events_;
1863 ASSERT_EQ(2u, track_events.size());
1864 ASSERT_EQ(1u, track_events[0].streams.size());
1865 EXPECT_EQ(kStreamId1, track_events[0].streams[0]->id());
1866 ASSERT_EQ(1u, track_events[1].streams.size());
1867 // This autogenerated a stream id for the empty one signalled.
1868 EXPECT_FALSE(track_events[1].streams[0]->id().empty());
1869}
1870
Steve Antone831b8c2018-02-01 12:22:16 -08001871TEST_F(PeerConnectionMsidSignalingTest, PureUnifiedPlanToUs) {
1872 auto caller = CreatePeerConnectionWithUnifiedPlan();
1873 caller->AddAudioTrack("caller_audio");
1874 auto callee = CreatePeerConnectionWithUnifiedPlan();
1875 callee->AddAudioTrack("callee_audio");
1876
1877 auto offer = caller->CreateOffer();
1878 // Simulate a pure Unified Plan offerer by setting the MSID signaling to media
1879 // section only.
1880 offer->description()->set_msid_signaling(cricket::kMsidSignalingMediaSection);
1881
1882 ASSERT_TRUE(
1883 caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1884 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1885
1886 // Answer should have only a=msid to match the offer.
1887 auto answer = callee->CreateAnswer();
1888 EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1889 answer->description()->msid_signaling());
1890}
1891
Steve Anton8e20f172018-03-06 10:55:04 -08001892// Test that the correct UMA metrics are reported for simple/complex SDP.
1893
Steve Anton3172c032018-05-03 15:30:18 -07001894class SdpFormatReceivedTest : public PeerConnectionRtpTestUnifiedPlan {};
Steve Anton8e20f172018-03-06 10:55:04 -08001895
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01001896#ifdef WEBRTC_HAVE_SCTP
Steve Anton8e20f172018-03-06 10:55:04 -08001897TEST_F(SdpFormatReceivedTest, DataChannelOnlyIsReportedAsNoTracks) {
1898 auto caller = CreatePeerConnectionWithUnifiedPlan();
1899 caller->CreateDataChannel("dc");
1900 auto callee = CreatePeerConnectionWithUnifiedPlan();
Steve Anton8e20f172018-03-06 10:55:04 -08001901
1902 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001903 // Note that only the callee does ReportSdpFormatReceived.
Ying Wangef3998f2019-12-09 13:06:53 +01001904 EXPECT_METRIC_THAT(
1905 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceived"),
1906 ElementsAre(Pair(kSdpFormatReceivedNoTracks, 1)));
Steve Anton8e20f172018-03-06 10:55:04 -08001907}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01001908#endif // WEBRTC_HAVE_SCTP
Steve Anton8e20f172018-03-06 10:55:04 -08001909
1910TEST_F(SdpFormatReceivedTest, SimpleUnifiedPlanIsReportedAsSimple) {
1911 auto caller = CreatePeerConnectionWithUnifiedPlan();
1912 caller->AddAudioTrack("audio");
1913 caller->AddVideoTrack("video");
1914 auto callee = CreatePeerConnectionWithPlanB();
Steve Anton8e20f172018-03-06 10:55:04 -08001915
1916 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001917 // Note that only the callee does ReportSdpFormatReceived.
Ying Wangef3998f2019-12-09 13:06:53 +01001918 EXPECT_METRIC_THAT(
1919 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceived"),
1920 ElementsAre(Pair(kSdpFormatReceivedSimple, 1)));
Steve Anton8e20f172018-03-06 10:55:04 -08001921}
1922
1923TEST_F(SdpFormatReceivedTest, SimplePlanBIsReportedAsSimple) {
1924 auto caller = CreatePeerConnectionWithPlanB();
1925 caller->AddVideoTrack("video"); // Video only.
1926 auto callee = CreatePeerConnectionWithUnifiedPlan();
Steve Anton8e20f172018-03-06 10:55:04 -08001927
1928 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
Steve Antonc1e6e862019-03-04 14:43:44 -08001929 // Note that only the callee does ReportSdpFormatReceived.
Ying Wangef3998f2019-12-09 13:06:53 +01001930 EXPECT_METRIC_THAT(
1931 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceived"),
1932 ElementsAre(Pair(kSdpFormatReceivedSimple, 1)));
Steve Anton8e20f172018-03-06 10:55:04 -08001933}
1934
1935TEST_F(SdpFormatReceivedTest, ComplexUnifiedIsReportedAsComplexUnifiedPlan) {
1936 auto caller = CreatePeerConnectionWithUnifiedPlan();
1937 caller->AddAudioTrack("audio1");
1938 caller->AddAudioTrack("audio2");
1939 caller->AddVideoTrack("video");
1940 auto callee = CreatePeerConnectionWithPlanB();
Steve Anton8e20f172018-03-06 10:55:04 -08001941
1942 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001943 // Note that only the callee does ReportSdpFormatReceived.
Ying Wangef3998f2019-12-09 13:06:53 +01001944 EXPECT_METRIC_THAT(
1945 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceived"),
1946 ElementsAre(Pair(kSdpFormatReceivedComplexUnifiedPlan, 1)));
Steve Anton8e20f172018-03-06 10:55:04 -08001947}
1948
1949TEST_F(SdpFormatReceivedTest, ComplexPlanBIsReportedAsComplexPlanB) {
1950 auto caller = CreatePeerConnectionWithPlanB();
1951 caller->AddVideoTrack("video1");
1952 caller->AddVideoTrack("video2");
1953 auto callee = CreatePeerConnectionWithUnifiedPlan();
Steve Anton8e20f172018-03-06 10:55:04 -08001954
Steve Antonba42e992018-04-09 14:10:01 -07001955 // This fails since Unified Plan cannot set a session description with
1956 // multiple "Plan B tracks" in the same media section. But we still expect the
1957 // SDP Format to be recorded.
1958 ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer()));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001959 // Note that only the callee does ReportSdpFormatReceived.
Ying Wangef3998f2019-12-09 13:06:53 +01001960 EXPECT_METRIC_THAT(
1961 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceived"),
1962 ElementsAre(Pair(kSdpFormatReceivedComplexPlanB, 1)));
Steve Anton8e20f172018-03-06 10:55:04 -08001963}
1964
Philipp Hanckeb8ca2a12020-10-07 12:47:10 +02001965TEST_F(SdpFormatReceivedTest, AnswerIsReported) {
1966 auto caller = CreatePeerConnectionWithPlanB();
1967 caller->AddAudioTrack("audio");
1968 caller->AddVideoTrack("video");
1969 auto callee = CreatePeerConnectionWithUnifiedPlan();
1970
1971 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1972 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
1973 EXPECT_METRIC_THAT(
1974 metrics::Samples("WebRTC.PeerConnection.SdpFormatReceivedAnswer"),
1975 ElementsAre(Pair(kSdpFormatReceivedSimple, 1)));
1976}
1977
Henrik Boström91d039b2018-01-11 17:43:30 +01001978// Sender setups in a call.
1979
Steve Anton3172c032018-05-03 15:30:18 -07001980TEST_P(PeerConnectionRtpTest, CreateTwoSendersWithSameTrack) {
Henrik Boström91d039b2018-01-11 17:43:30 +01001981 auto caller = CreatePeerConnection();
1982 auto callee = CreatePeerConnection();
1983
1984 auto track = caller->CreateAudioTrack("audio_track");
1985 auto sender1 = caller->AddTrack(track);
1986 ASSERT_TRUE(sender1);
1987 // We need to temporarily reset the track for the subsequent AddTrack() to
1988 // succeed.
1989 EXPECT_TRUE(sender1->SetTrack(nullptr));
1990 auto sender2 = caller->AddTrack(track);
1991 EXPECT_TRUE(sender2);
1992 EXPECT_TRUE(sender1->SetTrack(track));
1993
Florent Castelli15a38de2022-04-06 00:38:21 +02001994 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Steve Anton3172c032018-05-03 15:30:18 -07001995 // TODO(hbos): When https://crbug.com/webrtc/8734 is resolved, this should
Artem Titovcfea2182021-08-10 01:22:31 +02001996 // return true, and doing `callee->SetRemoteDescription()` should work.
Steve Anton3172c032018-05-03 15:30:18 -07001997 EXPECT_FALSE(caller->CreateOfferAndSetAsLocal());
1998 } else {
1999 EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
2000 }
Henrik Boström91d039b2018-01-11 17:43:30 +01002001}
2002
Guido Urdaneta70c2db12019-04-16 12:24:14 +02002003// This test exercises the code path that fires a NegotiationNeeded
2004// notification when the stream IDs of the local description differ from
Guido Urdaneta1ff16c82019-05-20 19:31:53 +02002005// the ones in the transceiver.
Guido Urdaneta70c2db12019-04-16 12:24:14 +02002006TEST_F(PeerConnectionRtpTestUnifiedPlan,
2007 ChangeAssociatedStreamsTriggersRenegotiation) {
2008 auto caller = CreatePeerConnection();
2009 auto callee = CreatePeerConnection();
2010
2011 RtpTransceiverInit init;
2012 init.direction = RtpTransceiverDirection::kSendRecv;
2013 auto transceiver =
2014 caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
Henrik Boströme574a312020-08-25 10:20:11 +02002015 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
2016 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Guido Urdaneta70c2db12019-04-16 12:24:14 +02002017
2018 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Henrik Boströme574a312020-08-25 10:20:11 +02002019 caller->observer()->clear_legacy_renegotiation_needed();
2020 caller->observer()->clear_latest_negotiation_needed_event();
Guido Urdaneta70c2db12019-04-16 12:24:14 +02002021
Guido Urdaneta1ff16c82019-05-20 19:31:53 +02002022 transceiver->sender()->SetStreams({"stream3", "stream4", "stream5"});
Henrik Boströme574a312020-08-25 10:20:11 +02002023 EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
2024 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
Guido Urdaneta1ff16c82019-05-20 19:31:53 +02002025
2026 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
2027 auto callee_streams = callee->pc()->GetReceivers()[0]->streams();
2028 ASSERT_EQ(3u, callee_streams.size());
2029 EXPECT_EQ("stream3", callee_streams[0]->id());
2030 EXPECT_EQ("stream4", callee_streams[1]->id());
2031 EXPECT_EQ("stream5", callee_streams[2]->id());
Guido Urdaneta70c2db12019-04-16 12:24:14 +02002032}
2033
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002034INSTANTIATE_TEST_SUITE_P(PeerConnectionRtpTest,
2035 PeerConnectionRtpTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002036 Values(SdpSemantics::kPlanB_DEPRECATED,
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002037 SdpSemantics::kUnifiedPlan));
Steve Anton3172c032018-05-03 15:30:18 -07002038
Steve Anton9158ef62017-11-27 13:01:52 -08002039} // namespace webrtc