blob: ffa53740eb27682a8e8d620a0418b5924fecc3f3 [file] [log] [blame]
Amit Hilbuchdd9390c2018-11-13 16:26:05 -08001/*
2 * Copyright 2018 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
Artem Titov880fa812021-07-30 22:30:23 +020011// This file contains tests for `RtpTransceiver`.
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080012
Steve Anton10542f22019-01-11 09:11:00 -080013#include "pc/rtp_transceiver.h"
Yves Gerey3e707812018-11-28 16:47:49 +010014
Markus Handell0357b3e2020-03-16 13:40:51 +010015#include <memory>
Harald Alvestrand3af79d12022-04-29 15:04:58 +000016#include <utility>
Markus Handell0357b3e2020-03-16 13:40:51 +010017
Harald Alvestrandc24a2182022-02-23 13:44:59 +000018#include "absl/strings/string_view.h"
Markus Handell5932fe12020-12-17 22:19:40 +010019#include "absl/types/optional.h"
20#include "api/rtp_parameters.h"
Markus Handell0357b3e2020-03-16 13:40:51 +010021#include "media/base/fake_media_engine.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000022#include "media/base/media_engine.h"
Harald Alvestrand9e334b72022-05-04 13:38:31 +000023#include "pc/channel_manager.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "pc/test/mock_channel_interface.h"
Markus Handell0357b3e2020-03-16 13:40:51 +010025#include "pc/test/mock_rtp_receiver_internal.h"
26#include "pc/test/mock_rtp_sender_internal.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000027#include "rtc_base/thread.h"
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080028#include "test/gmock.h"
Yves Gerey3e707812018-11-28 16:47:49 +010029#include "test/gtest.h"
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080030
Tommi99c8a802021-04-27 15:00:00 +020031using ::testing::_;
Markus Handell0357b3e2020-03-16 13:40:51 +010032using ::testing::ElementsAre;
Markus Handell5932fe12020-12-17 22:19:40 +010033using ::testing::Optional;
Markus Handell755c65d2020-06-24 01:06:10 +020034using ::testing::Property;
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080035using ::testing::Return;
36using ::testing::ReturnRef;
37
38namespace webrtc {
39
Tomas Gunnarsson16de2162022-01-26 10:21:57 +010040namespace {
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000041
42class RtpTransceiverTest : public testing::Test {
Tomas Gunnarsson16de2162022-01-26 10:21:57 +010043 public:
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000044 RtpTransceiverTest()
45 : channel_manager_(
46 cricket::ChannelManager::Create(&fake_media_engine_,
47 &ssrc_generator_,
48 true,
49 rtc::Thread::Current(),
50 rtc::Thread::Current())) {}
51
52 protected:
53 cricket::ChannelManager* channel_manager() { return channel_manager_.get(); }
54
55 private:
Niels Möller83830f32022-05-20 09:12:57 +020056 rtc::AutoThread main_thread_;
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000057 cricket::FakeMediaEngine fake_media_engine_;
58 rtc::UniqueRandomIdGenerator ssrc_generator_;
59 std::unique_ptr<cricket::ChannelManager> channel_manager_;
Tomas Gunnarsson16de2162022-01-26 10:21:57 +010060};
Tomas Gunnarsson16de2162022-01-26 10:21:57 +010061
Artem Titov880fa812021-07-30 22:30:23 +020062// Checks that a channel cannot be set on a stopped `RtpTransceiver`.
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000063TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +010064 const std::string content_name("my_mid");
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +010065 auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000066 cricket::MediaType::MEDIA_TYPE_AUDIO, channel_manager());
Harald Alvestrand3af79d12022-04-29 15:04:58 +000067 auto channel1 = std::make_unique<cricket::MockChannelInterface>();
68 EXPECT_CALL(*channel1, media_type())
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080069 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
Harald Alvestrand3af79d12022-04-29 15:04:58 +000070 EXPECT_CALL(*channel1, mid()).WillRepeatedly(ReturnRef(content_name));
71 EXPECT_CALL(*channel1, SetFirstPacketReceivedCallback(_));
72 EXPECT_CALL(*channel1, SetRtpTransport(_)).WillRepeatedly(Return(true));
73 auto channel1_ptr = channel1.get();
74 transceiver->SetChannel(std::move(channel1), [&](const std::string& mid) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +010075 EXPECT_EQ(mid, content_name);
76 return nullptr;
77 });
Harald Alvestrand3af79d12022-04-29 15:04:58 +000078 EXPECT_EQ(channel1_ptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080079
80 // Stop the transceiver.
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +010081 transceiver->StopInternal();
Harald Alvestrand3af79d12022-04-29 15:04:58 +000082 EXPECT_EQ(channel1_ptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080083
Harald Alvestrand3af79d12022-04-29 15:04:58 +000084 auto channel2 = std::make_unique<cricket::MockChannelInterface>();
85 EXPECT_CALL(*channel2, media_type())
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080086 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
87
Harald Alvestranddaee8702022-04-29 11:42:55 +000088 // Clear the current channel - required to allow SetChannel()
Harald Alvestrand3af79d12022-04-29 15:04:58 +000089 EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
Harald Alvestranddaee8702022-04-29 11:42:55 +000090 transceiver->ClearChannel();
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080091 // Channel can no longer be set, so this call should be a no-op.
Harald Alvestrand3af79d12022-04-29 15:04:58 +000092 transceiver->SetChannel(std::move(channel2),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +010093 [](const std::string&) { return nullptr; });
Harald Alvestranddaee8702022-04-29 11:42:55 +000094 EXPECT_EQ(nullptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080095}
96
Artem Titov880fa812021-07-30 22:30:23 +020097// Checks that a channel can be unset on a stopped `RtpTransceiver`
Harald Alvestrand0ac50b92022-05-18 07:51:34 +000098TEST_F(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +010099 const std::string content_name("my_mid");
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100100 auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000101 cricket::MediaType::MEDIA_TYPE_VIDEO, channel_manager());
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000102 auto channel = std::make_unique<cricket::MockChannelInterface>();
103 EXPECT_CALL(*channel, media_type())
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800104 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000105 EXPECT_CALL(*channel, mid()).WillRepeatedly(ReturnRef(content_name));
106 EXPECT_CALL(*channel, SetFirstPacketReceivedCallback(_))
Tommi99c8a802021-04-27 15:00:00 +0200107 .WillRepeatedly(testing::Return());
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000108 EXPECT_CALL(*channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800109
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000110 auto channel_ptr = channel.get();
111 transceiver->SetChannel(std::move(channel), [&](const std::string& mid) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100112 EXPECT_EQ(mid, content_name);
113 return nullptr;
114 });
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000115 EXPECT_EQ(channel_ptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800116
117 // Stop the transceiver.
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100118 transceiver->StopInternal();
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000119 EXPECT_EQ(channel_ptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800120
Artem Titov880fa812021-07-30 22:30:23 +0200121 // Set the channel to `nullptr`.
Harald Alvestrand19ebabc2022-04-28 13:31:17 +0000122 transceiver->ClearChannel();
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100123 EXPECT_EQ(nullptr, transceiver->channel());
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800124}
125
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000126class RtpTransceiverUnifiedPlanTest : public RtpTransceiverTest {
Harald Alvestrandc75c4282020-08-26 12:17:54 +0000127 public:
128 RtpTransceiverUnifiedPlanTest()
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100129 : transceiver_(rtc::make_ref_counted<RtpTransceiver>(
130 RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
131 rtc::Thread::Current(),
132 sender_),
133 RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
134 rtc::Thread::Current(),
135 rtc::Thread::Current(),
136 receiver_),
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000137 channel_manager(),
138 channel_manager()->media_engine()->voice().GetRtpHeaderExtensions(),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100139 /* on_negotiation_needed= */ [] {})) {}
Harald Alvestrandc75c4282020-08-26 12:17:54 +0000140
Tommi99c8a802021-04-27 15:00:00 +0200141 static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
142 auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
143 EXPECT_CALL(*receiver.get(), media_type())
144 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
145 return receiver;
146 }
147
148 static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
149 auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
150 EXPECT_CALL(*sender.get(), media_type())
151 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
152 return sender;
153 }
154
Niels Möller83830f32022-05-20 09:12:57 +0200155 rtc::AutoThread main_thread_;
Tommi99c8a802021-04-27 15:00:00 +0200156 rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
157 rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100158 rtc::scoped_refptr<RtpTransceiver> transceiver_;
Harald Alvestrandc75c4282020-08-26 12:17:54 +0000159};
160
161// Basic tests for Stop()
162TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
Tommi6589def2022-02-17 23:36:47 +0100163 EXPECT_CALL(*receiver_.get(), Stop());
164 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200165 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
166 EXPECT_CALL(*sender_.get(), Stop());
167
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100168 EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver_->direction());
169 EXPECT_FALSE(transceiver_->current_direction());
170 transceiver_->StopStandard();
171 EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
172 EXPECT_FALSE(transceiver_->current_direction());
173 transceiver_->StopTransceiverProcedure();
174 EXPECT_TRUE(transceiver_->current_direction());
175 EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
Harald Alvestrandc75c4282020-08-26 12:17:54 +0000176 EXPECT_EQ(RtpTransceiverDirection::kStopped,
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100177 *transceiver_->current_direction());
Harald Alvestrandc75c4282020-08-26 12:17:54 +0000178}
179
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000180class RtpTransceiverTestForHeaderExtensions : public RtpTransceiverTest {
Markus Handell755c65d2020-06-24 01:06:10 +0200181 public:
182 RtpTransceiverTestForHeaderExtensions()
Tomas Gunnarsson16de2162022-01-26 10:21:57 +0100183 : extensions_(
Markus Handell755c65d2020-06-24 01:06:10 +0200184 {RtpHeaderExtensionCapability("uri1",
185 1,
186 RtpTransceiverDirection::kSendOnly),
187 RtpHeaderExtensionCapability("uri2",
188 2,
189 RtpTransceiverDirection::kRecvOnly),
190 RtpHeaderExtensionCapability(RtpExtension::kMidUri,
191 3,
192 RtpTransceiverDirection::kSendRecv),
193 RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri,
194 4,
195 RtpTransceiverDirection::kSendRecv)}),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100196 transceiver_(rtc::make_ref_counted<RtpTransceiver>(
197 RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
198 rtc::Thread::Current(),
199 sender_),
200 RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
201 rtc::Thread::Current(),
202 rtc::Thread::Current(),
203 receiver_),
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000204 channel_manager(),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100205 extensions_,
206 /* on_negotiation_needed= */ [] {})) {}
Markus Handell755c65d2020-06-24 01:06:10 +0200207
Tommi99c8a802021-04-27 15:00:00 +0200208 static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
209 auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
210 EXPECT_CALL(*receiver.get(), media_type())
211 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
212 return receiver;
213 }
214
215 static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
216 auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
217 EXPECT_CALL(*sender.get(), media_type())
218 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
219 return sender;
220 }
221
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000222 void ClearChannel() {
Tommi6589def2022-02-17 23:36:47 +0100223 EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
Harald Alvestrand19ebabc2022-04-28 13:31:17 +0000224 transceiver_->ClearChannel();
Tomas Gunnarsson16de2162022-01-26 10:21:57 +0100225 }
226
Niels Möller83830f32022-05-20 09:12:57 +0200227 rtc::AutoThread main_thread_;
Tommi99c8a802021-04-27 15:00:00 +0200228 rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
229 rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
230
Markus Handell755c65d2020-06-24 01:06:10 +0200231 std::vector<RtpHeaderExtensionCapability> extensions_;
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100232 rtc::scoped_refptr<RtpTransceiver> transceiver_;
Markus Handell755c65d2020-06-24 01:06:10 +0200233};
234
235TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) {
Tommi6589def2022-02-17 23:36:47 +0100236 EXPECT_CALL(*receiver_.get(), Stop());
237 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200238 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
239 EXPECT_CALL(*sender_.get(), Stop());
240
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100241 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
Markus Handell755c65d2020-06-24 01:06:10 +0200242}
243
244TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) {
Tommi6589def2022-02-17 23:36:47 +0100245 EXPECT_CALL(*receiver_.get(), Stop());
246 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200247 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
248 EXPECT_CALL(*sender_.get(), Stop());
249
Markus Handell755c65d2020-06-24 01:06:10 +0200250 auto modified_extensions = extensions_;
251 modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly;
252 EXPECT_TRUE(
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100253 transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
254 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
Markus Handell755c65d2020-06-24 01:06:10 +0200255 modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly;
256 EXPECT_TRUE(
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100257 transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
258 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
Markus Handell755c65d2020-06-24 01:06:10 +0200259 modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
260 EXPECT_TRUE(
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100261 transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
262 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
Markus Handell755c65d2020-06-24 01:06:10 +0200263 modified_extensions[0].direction = RtpTransceiverDirection::kInactive;
264 EXPECT_TRUE(
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100265 transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
266 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
Markus Handell755c65d2020-06-24 01:06:10 +0200267}
268
269TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) {
Tommi6589def2022-02-17 23:36:47 +0100270 EXPECT_CALL(*receiver_.get(), Stop());
271 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200272 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
273 EXPECT_CALL(*sender_.get(), Stop());
274
Markus Handell755c65d2020-06-24 01:06:10 +0200275 auto modified_extensions = extensions_;
276 modified_extensions[0].direction = RtpTransceiverDirection::kStopped;
277 EXPECT_TRUE(
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100278 transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
279 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
Markus Handell755c65d2020-06-24 01:06:10 +0200280}
281
282TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsUnsupportedExtension) {
Tommi6589def2022-02-17 23:36:47 +0100283 EXPECT_CALL(*receiver_.get(), Stop());
284 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200285 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
286 EXPECT_CALL(*sender_.get(), Stop());
287
Markus Handell755c65d2020-06-24 01:06:10 +0200288 std::vector<RtpHeaderExtensionCapability> modified_extensions(
289 {RtpHeaderExtensionCapability("uri3", 1,
290 RtpTransceiverDirection::kSendRecv)});
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100291 EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
Markus Handellc17bca72021-01-14 17:08:01 +0100292 Property(&RTCError::type, RTCErrorType::UNSUPPORTED_PARAMETER));
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100293 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
Markus Handell755c65d2020-06-24 01:06:10 +0200294}
295
296TEST_F(RtpTransceiverTestForHeaderExtensions,
297 RejectsStoppedMandatoryExtensions) {
Tommi6589def2022-02-17 23:36:47 +0100298 EXPECT_CALL(*receiver_.get(), Stop());
299 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200300 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
301 EXPECT_CALL(*sender_.get(), Stop());
302
Markus Handell755c65d2020-06-24 01:06:10 +0200303 std::vector<RtpHeaderExtensionCapability> modified_extensions = extensions_;
304 // Attempting to stop the mandatory MID extension.
305 modified_extensions[2].direction = RtpTransceiverDirection::kStopped;
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100306 EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
Markus Handell755c65d2020-06-24 01:06:10 +0200307 Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100308 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
Markus Handell755c65d2020-06-24 01:06:10 +0200309 modified_extensions = extensions_;
310 // Attempting to stop the mandatory video orientation extension.
311 modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100312 EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
Markus Handell755c65d2020-06-24 01:06:10 +0200313 Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100314 EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
Markus Handell0357b3e2020-03-16 13:40:51 +0100315}
316
Markus Handell5932fe12020-12-17 22:19:40 +0100317TEST_F(RtpTransceiverTestForHeaderExtensions,
318 NoNegotiatedHdrExtsWithoutChannel) {
Tommi6589def2022-02-17 23:36:47 +0100319 EXPECT_CALL(*receiver_.get(), Stop());
320 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200321 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
322 EXPECT_CALL(*sender_.get(), Stop());
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100323 EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
Markus Handell5932fe12020-12-17 22:19:40 +0100324}
325
326TEST_F(RtpTransceiverTestForHeaderExtensions,
327 NoNegotiatedHdrExtsWithChannelWithoutNegotiation) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100328 const std::string content_name("my_mid");
Tommi6589def2022-02-17 23:36:47 +0100329 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
330 EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
Tommi99c8a802021-04-27 15:00:00 +0200331 EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
332 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
333 EXPECT_CALL(*sender_.get(), Stop());
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000334 auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
335 auto mock_channel_ptr = mock_channel.get();
336 EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
337 EXPECT_CALL(*mock_channel, media_type())
Tommi99c8a802021-04-27 15:00:00 +0200338 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000339 EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
340 EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
341 EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
342 transceiver_->SetChannel(std::move(mock_channel),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100343 [](const std::string&) { return nullptr; });
344 EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
Tomas Gunnarsson16de2162022-01-26 10:21:57 +0100345
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000346 EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
347 ClearChannel();
Markus Handell5932fe12020-12-17 22:19:40 +0100348}
349
350TEST_F(RtpTransceiverTestForHeaderExtensions, ReturnsNegotiatedHdrExts) {
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100351 const std::string content_name("my_mid");
Tommi6589def2022-02-17 23:36:47 +0100352 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
353 EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
Tommi99c8a802021-04-27 15:00:00 +0200354 EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
355 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
356 EXPECT_CALL(*sender_.get(), Stop());
357
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000358 auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
359 auto mock_channel_ptr = mock_channel.get();
360 EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
361 EXPECT_CALL(*mock_channel, media_type())
Tommi99c8a802021-04-27 15:00:00 +0200362 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000363 EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
364 EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
365 EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
Tommicc7a3682021-05-04 14:59:38 +0200366
Markus Handell5932fe12020-12-17 22:19:40 +0100367 cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
368 webrtc::RtpExtension("uri2", 2)};
Tommicc7a3682021-05-04 14:59:38 +0200369 cricket::AudioContentDescription description;
370 description.set_rtp_header_extensions(extensions);
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100371 transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
Tommicc7a3682021-05-04 14:59:38 +0200372
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000373 transceiver_->SetChannel(std::move(mock_channel),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100374 [](const std::string&) { return nullptr; });
375 EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
Markus Handell5932fe12020-12-17 22:19:40 +0100376 ElementsAre(RtpHeaderExtensionCapability(
377 "uri1", 1, RtpTransceiverDirection::kSendRecv),
378 RtpHeaderExtensionCapability(
379 "uri2", 2, RtpTransceiverDirection::kSendRecv)));
Tomas Gunnarsson16de2162022-01-26 10:21:57 +0100380
Harald Alvestrand3af79d12022-04-29 15:04:58 +0000381 EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
382 ClearChannel();
Markus Handell5932fe12020-12-17 22:19:40 +0100383}
384
385TEST_F(RtpTransceiverTestForHeaderExtensions,
386 ReturnsNegotiatedHdrExtsSecondTime) {
Tommi6589def2022-02-17 23:36:47 +0100387 EXPECT_CALL(*receiver_.get(), Stop());
388 EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
Tommi99c8a802021-04-27 15:00:00 +0200389 EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
390 EXPECT_CALL(*sender_.get(), Stop());
391
Markus Handell5932fe12020-12-17 22:19:40 +0100392 cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
393 webrtc::RtpExtension("uri2", 2)};
Tommicc7a3682021-05-04 14:59:38 +0200394 cricket::AudioContentDescription description;
395 description.set_rtp_header_extensions(extensions);
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100396 transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
Markus Handell5932fe12020-12-17 22:19:40 +0100397
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100398 EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
Tommicc7a3682021-05-04 14:59:38 +0200399 ElementsAre(RtpHeaderExtensionCapability(
400 "uri1", 1, RtpTransceiverDirection::kSendRecv),
401 RtpHeaderExtensionCapability(
402 "uri2", 2, RtpTransceiverDirection::kSendRecv)));
Markus Handell5932fe12020-12-17 22:19:40 +0100403
404 extensions = {webrtc::RtpExtension("uri3", 4),
405 webrtc::RtpExtension("uri5", 6)};
Tommicc7a3682021-05-04 14:59:38 +0200406 description.set_rtp_header_extensions(extensions);
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100407 transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
Tommicc7a3682021-05-04 14:59:38 +0200408
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100409 EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
Markus Handell5932fe12020-12-17 22:19:40 +0100410 ElementsAre(RtpHeaderExtensionCapability(
411 "uri3", 4, RtpTransceiverDirection::kSendRecv),
412 RtpHeaderExtensionCapability(
413 "uri5", 6, RtpTransceiverDirection::kSendRecv)));
414}
415
Harald Alvestrand0ac50b92022-05-18 07:51:34 +0000416} // namespace
417
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800418} // namespace webrtc