1 /*
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
11 // This file contains tests for |RtpTransceiver|.
12
13 #include "pc/rtp_transceiver.h"
14
15 #include <memory>
16
17 #include "absl/types/optional.h"
18 #include "api/rtp_parameters.h"
19 #include "media/base/fake_media_engine.h"
20 #include "pc/test/mock_channel_interface.h"
21 #include "pc/test/mock_rtp_receiver_internal.h"
22 #include "pc/test/mock_rtp_sender_internal.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25
26 using ::testing::ElementsAre;
27 using ::testing::Optional;
28 using ::testing::Property;
29 using ::testing::Return;
30 using ::testing::ReturnRef;
31
32 namespace webrtc {
33
34 // Checks that a channel cannot be set on a stopped |RtpTransceiver|.
TEST(RtpTransceiverTest,CannotSetChannelOnStoppedTransceiver)35 TEST(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
36 RtpTransceiver transceiver(cricket::MediaType::MEDIA_TYPE_AUDIO);
37 cricket::MockChannelInterface channel1;
38 sigslot::signal1<cricket::ChannelInterface*> signal;
39 EXPECT_CALL(channel1, media_type())
40 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
41 EXPECT_CALL(channel1, SignalFirstPacketReceived())
42 .WillRepeatedly(ReturnRef(signal));
43
44 transceiver.SetChannel(&channel1);
45 EXPECT_EQ(&channel1, transceiver.channel());
46
47 // Stop the transceiver.
48 transceiver.StopInternal();
49 EXPECT_EQ(&channel1, transceiver.channel());
50
51 cricket::MockChannelInterface channel2;
52 EXPECT_CALL(channel2, media_type())
53 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
54
55 // Channel can no longer be set, so this call should be a no-op.
56 transceiver.SetChannel(&channel2);
57 EXPECT_EQ(&channel1, transceiver.channel());
58 }
59
60 // Checks that a channel can be unset on a stopped |RtpTransceiver|
TEST(RtpTransceiverTest,CanUnsetChannelOnStoppedTransceiver)61 TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
62 RtpTransceiver transceiver(cricket::MediaType::MEDIA_TYPE_VIDEO);
63 cricket::MockChannelInterface channel;
64 sigslot::signal1<cricket::ChannelInterface*> signal;
65 EXPECT_CALL(channel, media_type())
66 .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
67 EXPECT_CALL(channel, SignalFirstPacketReceived())
68 .WillRepeatedly(ReturnRef(signal));
69
70 transceiver.SetChannel(&channel);
71 EXPECT_EQ(&channel, transceiver.channel());
72
73 // Stop the transceiver.
74 transceiver.StopInternal();
75 EXPECT_EQ(&channel, transceiver.channel());
76
77 // Set the channel to |nullptr|.
78 transceiver.SetChannel(nullptr);
79 EXPECT_EQ(nullptr, transceiver.channel());
80 }
81
82 class RtpTransceiverUnifiedPlanTest : public ::testing::Test {
83 public:
RtpTransceiverUnifiedPlanTest()84 RtpTransceiverUnifiedPlanTest()
85 : channel_manager_(cricket::ChannelManager::Create(
86 std::make_unique<cricket::FakeMediaEngine>(),
87 std::make_unique<cricket::FakeDataEngine>(),
88 false,
89 rtc::Thread::Current(),
90 rtc::Thread::Current())),
91 transceiver_(RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
92 rtc::Thread::Current(),
93 new rtc::RefCountedObject<MockRtpSenderInternal>()),
94 RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
95 rtc::Thread::Current(),
96 new rtc::RefCountedObject<MockRtpReceiverInternal>()),
97 channel_manager_.get(),
98 channel_manager_->GetSupportedAudioRtpHeaderExtensions(),
99 /* on_negotiation_needed= */ [] {}) {}
100
101 std::unique_ptr<cricket::ChannelManager> channel_manager_;
102 RtpTransceiver transceiver_;
103 };
104
105 // Basic tests for Stop()
TEST_F(RtpTransceiverUnifiedPlanTest,StopSetsDirection)106 TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
107 EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver_.direction());
108 EXPECT_FALSE(transceiver_.current_direction());
109 transceiver_.StopStandard();
110 EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_.direction());
111 EXPECT_FALSE(transceiver_.current_direction());
112 transceiver_.StopTransceiverProcedure();
113 EXPECT_TRUE(transceiver_.current_direction());
114 EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_.direction());
115 EXPECT_EQ(RtpTransceiverDirection::kStopped,
116 *transceiver_.current_direction());
117 }
118
119 class RtpTransceiverTestForHeaderExtensions : public ::testing::Test {
120 public:
RtpTransceiverTestForHeaderExtensions()121 RtpTransceiverTestForHeaderExtensions()
122 : channel_manager_(cricket::ChannelManager::Create(
123 std::make_unique<cricket::FakeMediaEngine>(),
124 std::make_unique<cricket::FakeDataEngine>(),
125 false,
126 rtc::Thread::Current(),
127 rtc::Thread::Current())),
128 extensions_(
129 {RtpHeaderExtensionCapability("uri1",
130 1,
131 RtpTransceiverDirection::kSendOnly),
132 RtpHeaderExtensionCapability("uri2",
133 2,
134 RtpTransceiverDirection::kRecvOnly),
135 RtpHeaderExtensionCapability(RtpExtension::kMidUri,
136 3,
137 RtpTransceiverDirection::kSendRecv),
138 RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri,
139 4,
140 RtpTransceiverDirection::kSendRecv)}),
141 transceiver_(RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
142 rtc::Thread::Current(),
143 new rtc::RefCountedObject<MockRtpSenderInternal>()),
144 RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
145 rtc::Thread::Current(),
146 new rtc::RefCountedObject<MockRtpReceiverInternal>()),
147 channel_manager_.get(),
148 extensions_,
__anon14170bf50202null149 /* on_negotiation_needed= */ [] {}) {}
150
151 std::unique_ptr<cricket::ChannelManager> channel_manager_;
152 std::vector<RtpHeaderExtensionCapability> extensions_;
153 RtpTransceiver transceiver_;
154 };
155
TEST_F(RtpTransceiverTestForHeaderExtensions,OffersChannelManagerList)156 TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) {
157 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_);
158 }
159
TEST_F(RtpTransceiverTestForHeaderExtensions,ModifiesDirection)160 TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) {
161 auto modified_extensions = extensions_;
162 modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly;
163 EXPECT_TRUE(
164 transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok());
165 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions);
166 modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly;
167 EXPECT_TRUE(
168 transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok());
169 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions);
170 modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
171 EXPECT_TRUE(
172 transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok());
173 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions);
174 modified_extensions[0].direction = RtpTransceiverDirection::kInactive;
175 EXPECT_TRUE(
176 transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok());
177 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions);
178 }
179
TEST_F(RtpTransceiverTestForHeaderExtensions,AcceptsStoppedExtension)180 TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) {
181 auto modified_extensions = extensions_;
182 modified_extensions[0].direction = RtpTransceiverDirection::kStopped;
183 EXPECT_TRUE(
184 transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok());
185 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions);
186 }
187
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsUnsupportedExtension)188 TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsUnsupportedExtension) {
189 std::vector<RtpHeaderExtensionCapability> modified_extensions(
190 {RtpHeaderExtensionCapability("uri3", 1,
191 RtpTransceiverDirection::kSendRecv)});
192 EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions),
193 Property(&RTCError::type, RTCErrorType::UNSUPPORTED_PARAMETER));
194 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_);
195 }
196
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsStoppedMandatoryExtensions)197 TEST_F(RtpTransceiverTestForHeaderExtensions,
198 RejectsStoppedMandatoryExtensions) {
199 std::vector<RtpHeaderExtensionCapability> modified_extensions = extensions_;
200 // Attempting to stop the mandatory MID extension.
201 modified_extensions[2].direction = RtpTransceiverDirection::kStopped;
202 EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions),
203 Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
204 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_);
205 modified_extensions = extensions_;
206 // Attempting to stop the mandatory video orientation extension.
207 modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
208 EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions),
209 Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
210 EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_);
211 }
212
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithoutChannel)213 TEST_F(RtpTransceiverTestForHeaderExtensions,
214 NoNegotiatedHdrExtsWithoutChannel) {
215 EXPECT_THAT(transceiver_.HeaderExtensionsNegotiated(), ElementsAre());
216 }
217
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithChannelWithoutNegotiation)218 TEST_F(RtpTransceiverTestForHeaderExtensions,
219 NoNegotiatedHdrExtsWithChannelWithoutNegotiation) {
220 cricket::MockChannelInterface mock_channel;
221 sigslot::signal1<cricket::ChannelInterface*> signal;
222 ON_CALL(mock_channel, SignalFirstPacketReceived)
223 .WillByDefault(ReturnRef(signal));
224 transceiver_.SetChannel(&mock_channel);
225 EXPECT_THAT(transceiver_.HeaderExtensionsNegotiated(), ElementsAre());
226 }
227
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExts)228 TEST_F(RtpTransceiverTestForHeaderExtensions, ReturnsNegotiatedHdrExts) {
229 cricket::MockChannelInterface mock_channel;
230 sigslot::signal1<cricket::ChannelInterface*> signal;
231 ON_CALL(mock_channel, SignalFirstPacketReceived)
232 .WillByDefault(ReturnRef(signal));
233 cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
234 webrtc::RtpExtension("uri2", 2)};
235 EXPECT_CALL(mock_channel, GetNegotiatedRtpHeaderExtensions)
236 .WillOnce(Return(extensions));
237 transceiver_.SetChannel(&mock_channel);
238 EXPECT_THAT(transceiver_.HeaderExtensionsNegotiated(),
239 ElementsAre(RtpHeaderExtensionCapability(
240 "uri1", 1, RtpTransceiverDirection::kSendRecv),
241 RtpHeaderExtensionCapability(
242 "uri2", 2, RtpTransceiverDirection::kSendRecv)));
243 }
244
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExtsSecondTime)245 TEST_F(RtpTransceiverTestForHeaderExtensions,
246 ReturnsNegotiatedHdrExtsSecondTime) {
247 cricket::MockChannelInterface mock_channel;
248 sigslot::signal1<cricket::ChannelInterface*> signal;
249 ON_CALL(mock_channel, SignalFirstPacketReceived)
250 .WillByDefault(ReturnRef(signal));
251 cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
252 webrtc::RtpExtension("uri2", 2)};
253
254 EXPECT_CALL(mock_channel, GetNegotiatedRtpHeaderExtensions)
255 .WillOnce(Return(extensions));
256 transceiver_.SetChannel(&mock_channel);
257 transceiver_.HeaderExtensionsNegotiated();
258 testing::Mock::VerifyAndClearExpectations(&mock_channel);
259
260 extensions = {webrtc::RtpExtension("uri3", 4),
261 webrtc::RtpExtension("uri5", 6)};
262 EXPECT_CALL(mock_channel, GetNegotiatedRtpHeaderExtensions)
263 .WillOnce(Return(extensions));
264 EXPECT_THAT(transceiver_.HeaderExtensionsNegotiated(),
265 ElementsAre(RtpHeaderExtensionCapability(
266 "uri3", 4, RtpTransceiverDirection::kSendRecv),
267 RtpHeaderExtensionCapability(
268 "uri5", 6, RtpTransceiverDirection::kSendRecv)));
269 }
270
271 } // namespace webrtc
272