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