xref: /aosp_15_r20/external/webrtc/pc/rtp_transceiver_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker // This file contains tests for `RtpTransceiver`.
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include "pc/rtp_transceiver.h"
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <utility>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
22*d9f75844SAndroid Build Coastguard Worker #include "media/base/fake_media_engine.h"
23*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_engine.h"
24*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_channel_interface.h"
25*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_rtp_receiver_internal.h"
26*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_rtp_sender_internal.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
28*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
29*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
32*d9f75844SAndroid Build Coastguard Worker using ::testing::ElementsAre;
33*d9f75844SAndroid Build Coastguard Worker using ::testing::Optional;
34*d9f75844SAndroid Build Coastguard Worker using ::testing::Property;
35*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
36*d9f75844SAndroid Build Coastguard Worker using ::testing::ReturnRef;
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
39*d9f75844SAndroid Build Coastguard Worker 
40*d9f75844SAndroid Build Coastguard Worker namespace {
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker class RtpTransceiverTest : public testing::Test {
43*d9f75844SAndroid Build Coastguard Worker  public:
RtpTransceiverTest()44*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverTest()
45*d9f75844SAndroid Build Coastguard Worker       : dependencies_(MakeDependencies()),
46*d9f75844SAndroid Build Coastguard Worker         context_(ConnectionContext::Create(&dependencies_)) {}
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker  protected:
media_engine()49*d9f75844SAndroid Build Coastguard Worker   cricket::MediaEngineInterface* media_engine() {
50*d9f75844SAndroid Build Coastguard Worker     return context_->media_engine();
51*d9f75844SAndroid Build Coastguard Worker   }
context()52*d9f75844SAndroid Build Coastguard Worker   ConnectionContext* context() { return context_.get(); }
53*d9f75844SAndroid Build Coastguard Worker 
54*d9f75844SAndroid Build Coastguard Worker  private:
55*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
56*d9f75844SAndroid Build Coastguard Worker 
MakeDependencies()57*d9f75844SAndroid Build Coastguard Worker   static PeerConnectionFactoryDependencies MakeDependencies() {
58*d9f75844SAndroid Build Coastguard Worker     PeerConnectionFactoryDependencies d;
59*d9f75844SAndroid Build Coastguard Worker     d.network_thread = rtc::Thread::Current();
60*d9f75844SAndroid Build Coastguard Worker     d.worker_thread = rtc::Thread::Current();
61*d9f75844SAndroid Build Coastguard Worker     d.signaling_thread = rtc::Thread::Current();
62*d9f75844SAndroid Build Coastguard Worker     d.media_engine = std::make_unique<cricket::FakeMediaEngine>();
63*d9f75844SAndroid Build Coastguard Worker     return d;
64*d9f75844SAndroid Build Coastguard Worker   }
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryDependencies dependencies_;
67*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<ConnectionContext> context_;
68*d9f75844SAndroid Build Coastguard Worker };
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker // Checks that a channel cannot be set on a stopped `RtpTransceiver`.
TEST_F(RtpTransceiverTest,CannotSetChannelOnStoppedTransceiver)71*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
72*d9f75844SAndroid Build Coastguard Worker   const std::string content_name("my_mid");
73*d9f75844SAndroid Build Coastguard Worker   auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
74*d9f75844SAndroid Build Coastguard Worker       cricket::MediaType::MEDIA_TYPE_AUDIO, context());
75*d9f75844SAndroid Build Coastguard Worker   auto channel1 = std::make_unique<cricket::MockChannelInterface>();
76*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel1, media_type())
77*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
78*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel1, mid()).WillRepeatedly(ReturnRef(content_name));
79*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel1, SetFirstPacketReceivedCallback(_));
80*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel1, SetRtpTransport(_)).WillRepeatedly(Return(true));
81*d9f75844SAndroid Build Coastguard Worker   auto channel1_ptr = channel1.get();
82*d9f75844SAndroid Build Coastguard Worker   transceiver->SetChannel(std::move(channel1), [&](const std::string& mid) {
83*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(mid, content_name);
84*d9f75844SAndroid Build Coastguard Worker     return nullptr;
85*d9f75844SAndroid Build Coastguard Worker   });
86*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(channel1_ptr, transceiver->channel());
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   // Stop the transceiver.
89*d9f75844SAndroid Build Coastguard Worker   transceiver->StopInternal();
90*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(channel1_ptr, transceiver->channel());
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   auto channel2 = std::make_unique<cricket::MockChannelInterface>();
93*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel2, media_type())
94*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
95*d9f75844SAndroid Build Coastguard Worker 
96*d9f75844SAndroid Build Coastguard Worker   // Clear the current channel - required to allow SetChannel()
97*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
98*d9f75844SAndroid Build Coastguard Worker   transceiver->ClearChannel();
99*d9f75844SAndroid Build Coastguard Worker   // Channel can no longer be set, so this call should be a no-op.
100*d9f75844SAndroid Build Coastguard Worker   transceiver->SetChannel(std::move(channel2),
101*d9f75844SAndroid Build Coastguard Worker                           [](const std::string&) { return nullptr; });
102*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, transceiver->channel());
103*d9f75844SAndroid Build Coastguard Worker }
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker // Checks that a channel can be unset on a stopped `RtpTransceiver`
TEST_F(RtpTransceiverTest,CanUnsetChannelOnStoppedTransceiver)106*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
107*d9f75844SAndroid Build Coastguard Worker   const std::string content_name("my_mid");
108*d9f75844SAndroid Build Coastguard Worker   auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
109*d9f75844SAndroid Build Coastguard Worker       cricket::MediaType::MEDIA_TYPE_VIDEO, context());
110*d9f75844SAndroid Build Coastguard Worker   auto channel = std::make_unique<cricket::MockChannelInterface>();
111*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel, media_type())
112*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
113*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel, mid()).WillRepeatedly(ReturnRef(content_name));
114*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel, SetFirstPacketReceivedCallback(_))
115*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(testing::Return());
116*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker   auto channel_ptr = channel.get();
119*d9f75844SAndroid Build Coastguard Worker   transceiver->SetChannel(std::move(channel), [&](const std::string& mid) {
120*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(mid, content_name);
121*d9f75844SAndroid Build Coastguard Worker     return nullptr;
122*d9f75844SAndroid Build Coastguard Worker   });
123*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(channel_ptr, transceiver->channel());
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   // Stop the transceiver.
126*d9f75844SAndroid Build Coastguard Worker   transceiver->StopInternal();
127*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(channel_ptr, transceiver->channel());
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker   // Set the channel to `nullptr`.
130*d9f75844SAndroid Build Coastguard Worker   transceiver->ClearChannel();
131*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, transceiver->channel());
132*d9f75844SAndroid Build Coastguard Worker }
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker class RtpTransceiverUnifiedPlanTest : public RtpTransceiverTest {
135*d9f75844SAndroid Build Coastguard Worker  public:
RtpTransceiverUnifiedPlanTest()136*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverUnifiedPlanTest()
137*d9f75844SAndroid Build Coastguard Worker       : transceiver_(rtc::make_ref_counted<RtpTransceiver>(
138*d9f75844SAndroid Build Coastguard Worker             RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
139*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
140*d9f75844SAndroid Build Coastguard Worker                 sender_),
141*d9f75844SAndroid Build Coastguard Worker             RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
142*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
143*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
144*d9f75844SAndroid Build Coastguard Worker                 receiver_),
145*d9f75844SAndroid Build Coastguard Worker             context(),
146*d9f75844SAndroid Build Coastguard Worker             media_engine()->voice().GetRtpHeaderExtensions(),
147*d9f75844SAndroid Build Coastguard Worker             /* on_negotiation_needed= */ [] {})) {}
148*d9f75844SAndroid Build Coastguard Worker 
MockReceiver()149*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
150*d9f75844SAndroid Build Coastguard Worker     auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
151*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(*receiver.get(), media_type())
152*d9f75844SAndroid Build Coastguard Worker         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
153*d9f75844SAndroid Build Coastguard Worker     return receiver;
154*d9f75844SAndroid Build Coastguard Worker   }
155*d9f75844SAndroid Build Coastguard Worker 
MockSender()156*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
157*d9f75844SAndroid Build Coastguard Worker     auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
158*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(*sender.get(), media_type())
159*d9f75844SAndroid Build Coastguard Worker         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
160*d9f75844SAndroid Build Coastguard Worker     return sender;
161*d9f75844SAndroid Build Coastguard Worker   }
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
164*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
165*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
166*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<RtpTransceiver> transceiver_;
167*d9f75844SAndroid Build Coastguard Worker };
168*d9f75844SAndroid Build Coastguard Worker 
169*d9f75844SAndroid Build Coastguard Worker // Basic tests for Stop()
TEST_F(RtpTransceiverUnifiedPlanTest,StopSetsDirection)170*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
171*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
172*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
173*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
174*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
175*d9f75844SAndroid Build Coastguard Worker 
176*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver_->direction());
177*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(transceiver_->current_direction());
178*d9f75844SAndroid Build Coastguard Worker   transceiver_->StopStandard();
179*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
180*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(transceiver_->current_direction());
181*d9f75844SAndroid Build Coastguard Worker   transceiver_->StopTransceiverProcedure();
182*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver_->current_direction());
183*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
184*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped,
185*d9f75844SAndroid Build Coastguard Worker             *transceiver_->current_direction());
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker 
188*d9f75844SAndroid Build Coastguard Worker class RtpTransceiverTestForHeaderExtensions : public RtpTransceiverTest {
189*d9f75844SAndroid Build Coastguard Worker  public:
RtpTransceiverTestForHeaderExtensions()190*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverTestForHeaderExtensions()
191*d9f75844SAndroid Build Coastguard Worker       : extensions_(
192*d9f75844SAndroid Build Coastguard Worker             {RtpHeaderExtensionCapability("uri1",
193*d9f75844SAndroid Build Coastguard Worker                                           1,
194*d9f75844SAndroid Build Coastguard Worker                                           RtpTransceiverDirection::kSendOnly),
195*d9f75844SAndroid Build Coastguard Worker              RtpHeaderExtensionCapability("uri2",
196*d9f75844SAndroid Build Coastguard Worker                                           2,
197*d9f75844SAndroid Build Coastguard Worker                                           RtpTransceiverDirection::kRecvOnly),
198*d9f75844SAndroid Build Coastguard Worker              RtpHeaderExtensionCapability(RtpExtension::kMidUri,
199*d9f75844SAndroid Build Coastguard Worker                                           3,
200*d9f75844SAndroid Build Coastguard Worker                                           RtpTransceiverDirection::kSendRecv),
201*d9f75844SAndroid Build Coastguard Worker              RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri,
202*d9f75844SAndroid Build Coastguard Worker                                           4,
203*d9f75844SAndroid Build Coastguard Worker                                           RtpTransceiverDirection::kSendRecv)}),
204*d9f75844SAndroid Build Coastguard Worker         transceiver_(rtc::make_ref_counted<RtpTransceiver>(
205*d9f75844SAndroid Build Coastguard Worker             RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
206*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
207*d9f75844SAndroid Build Coastguard Worker                 sender_),
208*d9f75844SAndroid Build Coastguard Worker             RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
209*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
210*d9f75844SAndroid Build Coastguard Worker                 rtc::Thread::Current(),
211*d9f75844SAndroid Build Coastguard Worker                 receiver_),
212*d9f75844SAndroid Build Coastguard Worker             context(),
213*d9f75844SAndroid Build Coastguard Worker             extensions_,
__anon9397170d0602null214*d9f75844SAndroid Build Coastguard Worker             /* on_negotiation_needed= */ [] {})) {}
215*d9f75844SAndroid Build Coastguard Worker 
MockReceiver()216*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
217*d9f75844SAndroid Build Coastguard Worker     auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
218*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(*receiver.get(), media_type())
219*d9f75844SAndroid Build Coastguard Worker         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
220*d9f75844SAndroid Build Coastguard Worker     return receiver;
221*d9f75844SAndroid Build Coastguard Worker   }
222*d9f75844SAndroid Build Coastguard Worker 
MockSender()223*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
224*d9f75844SAndroid Build Coastguard Worker     auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
225*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(*sender.get(), media_type())
226*d9f75844SAndroid Build Coastguard Worker         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
227*d9f75844SAndroid Build Coastguard Worker     return sender;
228*d9f75844SAndroid Build Coastguard Worker   }
229*d9f75844SAndroid Build Coastguard Worker 
ClearChannel()230*d9f75844SAndroid Build Coastguard Worker   void ClearChannel() {
231*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
232*d9f75844SAndroid Build Coastguard Worker     transceiver_->ClearChannel();
233*d9f75844SAndroid Build Coastguard Worker   }
234*d9f75844SAndroid Build Coastguard Worker 
235*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
236*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
237*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
238*d9f75844SAndroid Build Coastguard Worker 
239*d9f75844SAndroid Build Coastguard Worker   std::vector<RtpHeaderExtensionCapability> extensions_;
240*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<RtpTransceiver> transceiver_;
241*d9f75844SAndroid Build Coastguard Worker };
242*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,OffersChannelManagerList)243*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) {
244*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
245*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
246*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
247*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
248*d9f75844SAndroid Build Coastguard Worker 
249*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,ModifiesDirection)252*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) {
253*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
254*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
255*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
256*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
257*d9f75844SAndroid Build Coastguard Worker 
258*d9f75844SAndroid Build Coastguard Worker   auto modified_extensions = extensions_;
259*d9f75844SAndroid Build Coastguard Worker   modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly;
260*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
261*d9f75844SAndroid Build Coastguard Worker       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
262*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
263*d9f75844SAndroid Build Coastguard Worker   modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly;
264*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
265*d9f75844SAndroid Build Coastguard Worker       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
266*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
267*d9f75844SAndroid Build Coastguard Worker   modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
268*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
269*d9f75844SAndroid Build Coastguard Worker       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
270*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
271*d9f75844SAndroid Build Coastguard Worker   modified_extensions[0].direction = RtpTransceiverDirection::kInactive;
272*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
273*d9f75844SAndroid Build Coastguard Worker       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
274*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
275*d9f75844SAndroid Build Coastguard Worker }
276*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,AcceptsStoppedExtension)277*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) {
278*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
279*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
280*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
281*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
282*d9f75844SAndroid Build Coastguard Worker 
283*d9f75844SAndroid Build Coastguard Worker   auto modified_extensions = extensions_;
284*d9f75844SAndroid Build Coastguard Worker   modified_extensions[0].direction = RtpTransceiverDirection::kStopped;
285*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
286*d9f75844SAndroid Build Coastguard Worker       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
287*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
288*d9f75844SAndroid Build Coastguard Worker }
289*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsUnsupportedExtension)290*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsUnsupportedExtension) {
291*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
292*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
293*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
294*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
295*d9f75844SAndroid Build Coastguard Worker 
296*d9f75844SAndroid Build Coastguard Worker   std::vector<RtpHeaderExtensionCapability> modified_extensions(
297*d9f75844SAndroid Build Coastguard Worker       {RtpHeaderExtensionCapability("uri3", 1,
298*d9f75844SAndroid Build Coastguard Worker                                     RtpTransceiverDirection::kSendRecv)});
299*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
300*d9f75844SAndroid Build Coastguard Worker               Property(&RTCError::type, RTCErrorType::UNSUPPORTED_PARAMETER));
301*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
302*d9f75844SAndroid Build Coastguard Worker }
303*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsStoppedMandatoryExtensions)304*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions,
305*d9f75844SAndroid Build Coastguard Worker        RejectsStoppedMandatoryExtensions) {
306*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
307*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
308*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
309*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
310*d9f75844SAndroid Build Coastguard Worker 
311*d9f75844SAndroid Build Coastguard Worker   std::vector<RtpHeaderExtensionCapability> modified_extensions = extensions_;
312*d9f75844SAndroid Build Coastguard Worker   // Attempting to stop the mandatory MID extension.
313*d9f75844SAndroid Build Coastguard Worker   modified_extensions[2].direction = RtpTransceiverDirection::kStopped;
314*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
315*d9f75844SAndroid Build Coastguard Worker               Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
316*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
317*d9f75844SAndroid Build Coastguard Worker   modified_extensions = extensions_;
318*d9f75844SAndroid Build Coastguard Worker   // Attempting to stop the mandatory video orientation extension.
319*d9f75844SAndroid Build Coastguard Worker   modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
320*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
321*d9f75844SAndroid Build Coastguard Worker               Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
322*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
323*d9f75844SAndroid Build Coastguard Worker }
324*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithoutChannel)325*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions,
326*d9f75844SAndroid Build Coastguard Worker        NoNegotiatedHdrExtsWithoutChannel) {
327*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
328*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
329*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
330*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
331*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
332*d9f75844SAndroid Build Coastguard Worker }
333*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithChannelWithoutNegotiation)334*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions,
335*d9f75844SAndroid Build Coastguard Worker        NoNegotiatedHdrExtsWithChannelWithoutNegotiation) {
336*d9f75844SAndroid Build Coastguard Worker   const std::string content_name("my_mid");
337*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
338*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
339*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
340*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
341*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
342*d9f75844SAndroid Build Coastguard Worker   auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
343*d9f75844SAndroid Build Coastguard Worker   auto mock_channel_ptr = mock_channel.get();
344*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
345*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, media_type())
346*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
347*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
348*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
349*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
350*d9f75844SAndroid Build Coastguard Worker   transceiver_->SetChannel(std::move(mock_channel),
351*d9f75844SAndroid Build Coastguard Worker                            [](const std::string&) { return nullptr; });
352*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
353*d9f75844SAndroid Build Coastguard Worker 
354*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
355*d9f75844SAndroid Build Coastguard Worker   ClearChannel();
356*d9f75844SAndroid Build Coastguard Worker }
357*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExts)358*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions, ReturnsNegotiatedHdrExts) {
359*d9f75844SAndroid Build Coastguard Worker   const std::string content_name("my_mid");
360*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
361*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
362*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
363*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
364*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
365*d9f75844SAndroid Build Coastguard Worker 
366*d9f75844SAndroid Build Coastguard Worker   auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
367*d9f75844SAndroid Build Coastguard Worker   auto mock_channel_ptr = mock_channel.get();
368*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
369*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, media_type())
370*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
371*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
372*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
373*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
374*d9f75844SAndroid Build Coastguard Worker 
375*d9f75844SAndroid Build Coastguard Worker   cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
376*d9f75844SAndroid Build Coastguard Worker                                              webrtc::RtpExtension("uri2", 2)};
377*d9f75844SAndroid Build Coastguard Worker   cricket::AudioContentDescription description;
378*d9f75844SAndroid Build Coastguard Worker   description.set_rtp_header_extensions(extensions);
379*d9f75844SAndroid Build Coastguard Worker   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
380*d9f75844SAndroid Build Coastguard Worker 
381*d9f75844SAndroid Build Coastguard Worker   transceiver_->SetChannel(std::move(mock_channel),
382*d9f75844SAndroid Build Coastguard Worker                            [](const std::string&) { return nullptr; });
383*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
384*d9f75844SAndroid Build Coastguard Worker               ElementsAre(RtpHeaderExtensionCapability(
385*d9f75844SAndroid Build Coastguard Worker                               "uri1", 1, RtpTransceiverDirection::kSendRecv),
386*d9f75844SAndroid Build Coastguard Worker                           RtpHeaderExtensionCapability(
387*d9f75844SAndroid Build Coastguard Worker                               "uri2", 2, RtpTransceiverDirection::kSendRecv)));
388*d9f75844SAndroid Build Coastguard Worker 
389*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
390*d9f75844SAndroid Build Coastguard Worker   ClearChannel();
391*d9f75844SAndroid Build Coastguard Worker }
392*d9f75844SAndroid Build Coastguard Worker 
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExtsSecondTime)393*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpTransceiverTestForHeaderExtensions,
394*d9f75844SAndroid Build Coastguard Worker        ReturnsNegotiatedHdrExtsSecondTime) {
395*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), Stop());
396*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
397*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
398*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*sender_.get(), Stop());
399*d9f75844SAndroid Build Coastguard Worker 
400*d9f75844SAndroid Build Coastguard Worker   cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
401*d9f75844SAndroid Build Coastguard Worker                                              webrtc::RtpExtension("uri2", 2)};
402*d9f75844SAndroid Build Coastguard Worker   cricket::AudioContentDescription description;
403*d9f75844SAndroid Build Coastguard Worker   description.set_rtp_header_extensions(extensions);
404*d9f75844SAndroid Build Coastguard Worker   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
405*d9f75844SAndroid Build Coastguard Worker 
406*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
407*d9f75844SAndroid Build Coastguard Worker               ElementsAre(RtpHeaderExtensionCapability(
408*d9f75844SAndroid Build Coastguard Worker                               "uri1", 1, RtpTransceiverDirection::kSendRecv),
409*d9f75844SAndroid Build Coastguard Worker                           RtpHeaderExtensionCapability(
410*d9f75844SAndroid Build Coastguard Worker                               "uri2", 2, RtpTransceiverDirection::kSendRecv)));
411*d9f75844SAndroid Build Coastguard Worker 
412*d9f75844SAndroid Build Coastguard Worker   extensions = {webrtc::RtpExtension("uri3", 4),
413*d9f75844SAndroid Build Coastguard Worker                 webrtc::RtpExtension("uri5", 6)};
414*d9f75844SAndroid Build Coastguard Worker   description.set_rtp_header_extensions(extensions);
415*d9f75844SAndroid Build Coastguard Worker   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
416*d9f75844SAndroid Build Coastguard Worker 
417*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
418*d9f75844SAndroid Build Coastguard Worker               ElementsAre(RtpHeaderExtensionCapability(
419*d9f75844SAndroid Build Coastguard Worker                               "uri3", 4, RtpTransceiverDirection::kSendRecv),
420*d9f75844SAndroid Build Coastguard Worker                           RtpHeaderExtensionCapability(
421*d9f75844SAndroid Build Coastguard Worker                               "uri5", 6, RtpTransceiverDirection::kSendRecv)));
422*d9f75844SAndroid Build Coastguard Worker }
423*d9f75844SAndroid Build Coastguard Worker 
424*d9f75844SAndroid Build Coastguard Worker }  // namespace
425*d9f75844SAndroid Build Coastguard Worker 
426*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
427