xref: /aosp_15_r20/external/webrtc/pc/peer_connection_rtp_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2017 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 #include <stddef.h>
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker #include <utility>
17*d9f75844SAndroid Build Coastguard Worker #include <vector>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/jsep.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/media_stream_interface.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/media_types.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_receiver_interface.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_sender_interface.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_direction.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_interface.h"
34*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
35*d9f75844SAndroid Build Coastguard Worker #include "api/set_remote_description_observer_interface.h"
36*d9f75844SAndroid Build Coastguard Worker #include "api/uma_metrics.h"
37*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
38*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
39*d9f75844SAndroid Build Coastguard Worker #include "media/base/stream_params.h"
40*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
41*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
42*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
43*d9f75844SAndroid Build Coastguard Worker #include "pc/media_session.h"
44*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_wrapper.h"
45*d9f75844SAndroid Build Coastguard Worker #include "pc/sdp_utils.h"
46*d9f75844SAndroid Build Coastguard Worker #include "pc/session_description.h"
47*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_audio_capture_module.h"
48*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
49*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
50*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
51*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate_generator.h"
52*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
53*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/metrics.h"
54*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
55*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker // This file contains tests for RTP Media API-related behavior of
58*d9f75844SAndroid Build Coastguard Worker // `webrtc::PeerConnection`, see https://w3c.github.io/webrtc-pc/#rtp-media-api.
59*d9f75844SAndroid Build Coastguard Worker 
60*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
63*d9f75844SAndroid Build Coastguard Worker using ::testing::ElementsAre;
64*d9f75844SAndroid Build Coastguard Worker using ::testing::Pair;
65*d9f75844SAndroid Build Coastguard Worker using ::testing::UnorderedElementsAre;
66*d9f75844SAndroid Build Coastguard Worker using ::testing::Values;
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker const uint32_t kDefaultTimeout = 10000u;
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker template <typename MethodFunctor>
71*d9f75844SAndroid Build Coastguard Worker class OnSuccessObserver : public webrtc::SetRemoteDescriptionObserverInterface {
72*d9f75844SAndroid Build Coastguard Worker  public:
OnSuccessObserver(MethodFunctor on_success)73*d9f75844SAndroid Build Coastguard Worker   explicit OnSuccessObserver(MethodFunctor on_success)
74*d9f75844SAndroid Build Coastguard Worker       : on_success_(std::move(on_success)) {}
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker   // webrtc::SetRemoteDescriptionObserverInterface implementation.
OnSetRemoteDescriptionComplete(webrtc::RTCError error)77*d9f75844SAndroid Build Coastguard Worker   void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
78*d9f75844SAndroid Build Coastguard Worker     RTC_CHECK(error.ok());
79*d9f75844SAndroid Build Coastguard Worker     on_success_();
80*d9f75844SAndroid Build Coastguard Worker   }
81*d9f75844SAndroid Build Coastguard Worker 
82*d9f75844SAndroid Build Coastguard Worker  private:
83*d9f75844SAndroid Build Coastguard Worker   MethodFunctor on_success_;
84*d9f75844SAndroid Build Coastguard Worker };
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker class PeerConnectionRtpBaseTest : public ::testing::Test {
87*d9f75844SAndroid Build Coastguard Worker  public:
PeerConnectionRtpBaseTest(SdpSemantics sdp_semantics)88*d9f75844SAndroid Build Coastguard Worker   explicit PeerConnectionRtpBaseTest(SdpSemantics sdp_semantics)
89*d9f75844SAndroid Build Coastguard Worker       : sdp_semantics_(sdp_semantics),
90*d9f75844SAndroid Build Coastguard Worker         pc_factory_(
91*d9f75844SAndroid Build Coastguard Worker             CreatePeerConnectionFactory(rtc::Thread::Current(),
92*d9f75844SAndroid Build Coastguard Worker                                         rtc::Thread::Current(),
93*d9f75844SAndroid Build Coastguard Worker                                         rtc::Thread::Current(),
94*d9f75844SAndroid Build Coastguard Worker                                         FakeAudioCaptureModule::Create(),
95*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinAudioEncoderFactory(),
96*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinAudioDecoderFactory(),
97*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinVideoEncoderFactory(),
98*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinVideoDecoderFactory(),
99*d9f75844SAndroid Build Coastguard Worker                                         nullptr /* audio_mixer */,
100*d9f75844SAndroid Build Coastguard Worker                                         nullptr /* audio_processing */)) {
101*d9f75844SAndroid Build Coastguard Worker     webrtc::metrics::Reset();
102*d9f75844SAndroid Build Coastguard Worker   }
103*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection()104*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection() {
105*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnection(RTCConfiguration());
106*d9f75844SAndroid Build Coastguard Worker   }
107*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionWithPlanB()108*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithPlanB() {
109*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration config;
110*d9f75844SAndroid Build Coastguard Worker     config.sdp_semantics = SdpSemantics::kPlanB_DEPRECATED;
111*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionInternal(config);
112*d9f75844SAndroid Build Coastguard Worker   }
113*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionWithUnifiedPlan()114*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithUnifiedPlan() {
115*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration config;
116*d9f75844SAndroid Build Coastguard Worker     config.sdp_semantics = SdpSemantics::kUnifiedPlan;
117*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionInternal(config);
118*d9f75844SAndroid Build Coastguard Worker   }
119*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection(const RTCConfiguration & config)120*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
121*d9f75844SAndroid Build Coastguard Worker       const RTCConfiguration& config) {
122*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration modified_config = config;
123*d9f75844SAndroid Build Coastguard Worker     modified_config.sdp_semantics = sdp_semantics_;
124*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionInternal(modified_config);
125*d9f75844SAndroid Build Coastguard Worker   }
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker  protected:
128*d9f75844SAndroid Build Coastguard Worker   const SdpSemantics sdp_semantics_;
129*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker  private:
132*d9f75844SAndroid Build Coastguard Worker   // Private so that tests don't accidentally bypass the SdpSemantics
133*d9f75844SAndroid Build Coastguard Worker   // adjustment.
CreatePeerConnectionInternal(const RTCConfiguration & config)134*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionInternal(
135*d9f75844SAndroid Build Coastguard Worker       const RTCConfiguration& config) {
136*d9f75844SAndroid Build Coastguard Worker     auto observer = std::make_unique<MockPeerConnectionObserver>();
137*d9f75844SAndroid Build Coastguard Worker     auto result = pc_factory_->CreatePeerConnectionOrError(
138*d9f75844SAndroid Build Coastguard Worker         config, PeerConnectionDependencies(observer.get()));
139*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(result.ok());
140*d9f75844SAndroid Build Coastguard Worker     observer->SetPeerConnectionInterface(result.value().get());
141*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<PeerConnectionWrapper>(
142*d9f75844SAndroid Build Coastguard Worker         pc_factory_, result.MoveValue(), std::move(observer));
143*d9f75844SAndroid Build Coastguard Worker   }
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
146*d9f75844SAndroid Build Coastguard Worker };
147*d9f75844SAndroid Build Coastguard Worker 
148*d9f75844SAndroid Build Coastguard Worker class PeerConnectionRtpTest
149*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionRtpBaseTest,
150*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<SdpSemantics> {
151*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionRtpTest()152*d9f75844SAndroid Build Coastguard Worker   PeerConnectionRtpTest() : PeerConnectionRtpBaseTest(GetParam()) {}
153*d9f75844SAndroid Build Coastguard Worker };
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker class PeerConnectionRtpTestPlanB : public PeerConnectionRtpBaseTest {
156*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionRtpTestPlanB()157*d9f75844SAndroid Build Coastguard Worker   PeerConnectionRtpTestPlanB()
158*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionRtpBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
159*d9f75844SAndroid Build Coastguard Worker };
160*d9f75844SAndroid Build Coastguard Worker 
161*d9f75844SAndroid Build Coastguard Worker class PeerConnectionRtpTestUnifiedPlan : public PeerConnectionRtpBaseTest {
162*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionRtpTestUnifiedPlan()163*d9f75844SAndroid Build Coastguard Worker   PeerConnectionRtpTestUnifiedPlan()
164*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionRtpBaseTest(SdpSemantics::kUnifiedPlan) {}
165*d9f75844SAndroid Build Coastguard Worker 
166*d9f75844SAndroid Build Coastguard Worker   // Helper to emulate an SFU that rejects an offered media section
167*d9f75844SAndroid Build Coastguard Worker   // in answer.
ExchangeOfferAnswerWhereRemoteStopsTransceiver(PeerConnectionWrapper * caller,PeerConnectionWrapper * callee,size_t mid_to_stop)168*d9f75844SAndroid Build Coastguard Worker   bool ExchangeOfferAnswerWhereRemoteStopsTransceiver(
169*d9f75844SAndroid Build Coastguard Worker       PeerConnectionWrapper* caller,
170*d9f75844SAndroid Build Coastguard Worker       PeerConnectionWrapper* callee,
171*d9f75844SAndroid Build Coastguard Worker       size_t mid_to_stop) {
172*d9f75844SAndroid Build Coastguard Worker     auto offer = caller->CreateOffer();
173*d9f75844SAndroid Build Coastguard Worker     caller->SetLocalDescription(CloneSessionDescription(offer.get()));
174*d9f75844SAndroid Build Coastguard Worker     callee->SetRemoteDescription(std::move(offer));
175*d9f75844SAndroid Build Coastguard Worker     EXPECT_LT(mid_to_stop, callee->pc()->GetTransceivers().size());
176*d9f75844SAndroid Build Coastguard Worker     // Must use StopInternal in order to do instant reject.
177*d9f75844SAndroid Build Coastguard Worker     callee->pc()->GetTransceivers()[mid_to_stop]->StopInternal();
178*d9f75844SAndroid Build Coastguard Worker     auto answer = callee->CreateAnswer();
179*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(answer);
180*d9f75844SAndroid Build Coastguard Worker     bool set_local_answer =
181*d9f75844SAndroid Build Coastguard Worker         callee->SetLocalDescription(CloneSessionDescription(answer.get()));
182*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(set_local_answer);
183*d9f75844SAndroid Build Coastguard Worker     bool set_remote_answer = caller->SetRemoteDescription(std::move(answer));
184*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(set_remote_answer);
185*d9f75844SAndroid Build Coastguard Worker     return set_remote_answer;
186*d9f75844SAndroid Build Coastguard Worker   }
187*d9f75844SAndroid Build Coastguard Worker };
188*d9f75844SAndroid Build Coastguard Worker 
189*d9f75844SAndroid Build Coastguard Worker // These tests cover `webrtc::PeerConnectionObserver` callbacks firing upon
190*d9f75844SAndroid Build Coastguard Worker // setting the remote description.
191*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,AddTrackWithoutStreamFiresOnAddTrack)192*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamFiresOnAddTrack) {
193*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
194*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
195*d9f75844SAndroid Build Coastguard Worker 
196*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("audio_track"));
197*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
198*d9f75844SAndroid Build Coastguard Worker 
199*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
200*d9f75844SAndroid Build Coastguard Worker   const auto& add_track_event = callee->observer()->add_track_events_[0];
201*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
204*d9f75844SAndroid Build Coastguard Worker     // Since we are not supporting the no stream case with Plan B, there should
205*d9f75844SAndroid Build Coastguard Worker     // be a generated stream, even though we didn't set one with AddTrack.
206*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, add_track_event.streams.size());
207*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
208*d9f75844SAndroid Build Coastguard Worker   } else {
209*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0u, add_track_event.streams.size());
210*d9f75844SAndroid Build Coastguard Worker   }
211*d9f75844SAndroid Build Coastguard Worker }
212*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,AddTrackWithStreamFiresOnAddTrack)213*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, AddTrackWithStreamFiresOnAddTrack) {
214*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
215*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
216*d9f75844SAndroid Build Coastguard Worker 
217*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
218*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
219*d9f75844SAndroid Build Coastguard Worker 
220*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
221*d9f75844SAndroid Build Coastguard Worker   auto& add_track_event = callee->observer()->add_track_events_[0];
222*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(add_track_event.streams.size(), 1u);
223*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("audio_stream", add_track_event.streams[0]->id());
224*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
225*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
226*d9f75844SAndroid Build Coastguard Worker }
227*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithoutStreamFiresOnRemoveTrack)228*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamFiresOnRemoveTrack) {
229*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
230*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
231*d9f75844SAndroid Build Coastguard Worker 
232*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {});
233*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
234*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
235*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
236*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
237*d9f75844SAndroid Build Coastguard Worker 
238*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
239*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
240*d9f75844SAndroid Build Coastguard Worker 
241*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
242*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
243*d9f75844SAndroid Build Coastguard Worker             callee->observer()->remove_track_events_);
244*d9f75844SAndroid Build Coastguard Worker }
245*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithStreamFiresOnRemoveTrack)246*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamFiresOnRemoveTrack) {
247*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
248*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
249*d9f75844SAndroid Build Coastguard Worker 
250*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
251*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
252*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
253*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
254*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
255*d9f75844SAndroid Build Coastguard Worker 
256*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
257*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
258*d9f75844SAndroid Build Coastguard Worker 
259*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
260*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
261*d9f75844SAndroid Build Coastguard Worker             callee->observer()->remove_track_events_);
262*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
263*d9f75844SAndroid Build Coastguard Worker }
264*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithSharedStreamFiresOnRemoveTrack)265*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamFiresOnRemoveTrack) {
266*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
267*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
268*d9f75844SAndroid Build Coastguard Worker 
269*d9f75844SAndroid Build Coastguard Worker   const char kSharedStreamId[] = "shared_audio_stream";
270*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
271*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
272*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
273*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
274*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
275*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
276*d9f75844SAndroid Build Coastguard Worker 
277*d9f75844SAndroid Build Coastguard Worker   // Remove "audio_track1".
278*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender1).ok());
279*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
280*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
281*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
282*d9f75844SAndroid Build Coastguard Worker       std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
283*d9f75844SAndroid Build Coastguard Worker           callee->observer()->add_track_events_[0].receiver},
284*d9f75844SAndroid Build Coastguard Worker       callee->observer()->remove_track_events_);
285*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee->observer()->remote_streams()->count());
286*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
287*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
288*d9f75844SAndroid Build Coastguard Worker 
289*d9f75844SAndroid Build Coastguard Worker   // Remove "audio_track2".
290*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender2).ok());
291*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
292*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
293*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
294*d9f75844SAndroid Build Coastguard Worker             callee->observer()->remove_track_events_);
295*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->observer()->remote_streams()->count());
296*d9f75844SAndroid Build Coastguard Worker }
297*d9f75844SAndroid Build Coastguard Worker 
298*d9f75844SAndroid Build Coastguard Worker // Tests the edge case that if a stream ID changes for a given track that both
299*d9f75844SAndroid Build Coastguard Worker // OnRemoveTrack and OnAddTrack is fired.
TEST_F(PeerConnectionRtpTestPlanB,RemoteStreamIdChangesFiresOnRemoveAndOnAddTrack)300*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestPlanB,
301*d9f75844SAndroid Build Coastguard Worker        RemoteStreamIdChangesFiresOnRemoveAndOnAddTrack) {
302*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
303*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
304*d9f75844SAndroid Build Coastguard Worker 
305*d9f75844SAndroid Build Coastguard Worker   const char kStreamId1[] = "stream1";
306*d9f75844SAndroid Build Coastguard Worker   const char kStreamId2[] = "stream2";
307*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track1", {kStreamId1});
308*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
309*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
310*d9f75844SAndroid Build Coastguard Worker 
311*d9f75844SAndroid Build Coastguard Worker   // Change the stream ID of the sender in the session description.
312*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
313*d9f75844SAndroid Build Coastguard Worker   auto* audio_desc =
314*d9f75844SAndroid Build Coastguard Worker       cricket::GetFirstAudioContentDescription(offer->description());
315*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(audio_desc->mutable_streams().size(), 1u);
316*d9f75844SAndroid Build Coastguard Worker   audio_desc->mutable_streams()[0].set_stream_ids({kStreamId2});
317*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
318*d9f75844SAndroid Build Coastguard Worker 
319*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
320*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->add_track_events_[1].streams[0]->id(),
321*d9f75844SAndroid Build Coastguard Worker             kStreamId2);
322*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->remove_track_events_.size(), 1u);
323*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->remove_track_events_[0]->streams()[0]->id(),
324*d9f75844SAndroid Build Coastguard Worker             kStreamId1);
325*d9f75844SAndroid Build Coastguard Worker }
326*d9f75844SAndroid Build Coastguard Worker 
327*d9f75844SAndroid Build Coastguard Worker // Tests that setting a remote description with sending transceivers will fire
328*d9f75844SAndroid Build Coastguard Worker // the OnTrack callback for each transceiver and setting a remote description
329*d9f75844SAndroid Build Coastguard Worker // with receive only transceivers will not call OnTrack. One transceiver is
330*d9f75844SAndroid Build Coastguard Worker // created without any stream_ids, while the other is created with multiple
331*d9f75844SAndroid Build Coastguard Worker // stream_ids.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverCallsOnTrack)332*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverCallsOnTrack) {
333*d9f75844SAndroid Build Coastguard Worker   const std::string kStreamId1 = "video_stream1";
334*d9f75844SAndroid Build Coastguard Worker   const std::string kStreamId2 = "video_stream2";
335*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
336*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
337*d9f75844SAndroid Build Coastguard Worker 
338*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
339*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit video_transceiver_init;
340*d9f75844SAndroid Build Coastguard Worker   video_transceiver_init.stream_ids = {kStreamId1, kStreamId2};
341*d9f75844SAndroid Build Coastguard Worker   auto video_transceiver =
342*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, video_transceiver_init);
343*d9f75844SAndroid Build Coastguard Worker 
344*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
345*d9f75844SAndroid Build Coastguard Worker 
346*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(0u, caller->observer()->on_track_transceivers_.size());
347*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee->observer()->on_track_transceivers_.size());
348*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_transceiver->mid(),
349*d9f75844SAndroid Build Coastguard Worker             callee->pc()->GetTransceivers()[0]->mid());
350*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(video_transceiver->mid(),
351*d9f75844SAndroid Build Coastguard Worker             callee->pc()->GetTransceivers()[1]->mid());
352*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::scoped_refptr<MediaStreamInterface>> audio_streams =
353*d9f75844SAndroid Build Coastguard Worker       callee->pc()->GetTransceivers()[0]->receiver()->streams();
354*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::scoped_refptr<MediaStreamInterface>> video_streams =
355*d9f75844SAndroid Build Coastguard Worker       callee->pc()->GetTransceivers()[1]->receiver()->streams();
356*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(0u, audio_streams.size());
357*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, video_streams.size());
358*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kStreamId1, video_streams[0]->id());
359*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kStreamId2, video_streams[1]->id());
360*d9f75844SAndroid Build Coastguard Worker }
361*d9f75844SAndroid Build Coastguard Worker 
362*d9f75844SAndroid Build Coastguard Worker // Test that doing additional offer/answer exchanges with no changes to tracks
363*d9f75844SAndroid Build Coastguard Worker // will cause no additional OnTrack calls after the tracks have been negotiated.
TEST_F(PeerConnectionRtpTestUnifiedPlan,ReofferDoesNotCallOnTrack)364*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, ReofferDoesNotCallOnTrack) {
365*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
366*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
367*d9f75844SAndroid Build Coastguard Worker 
368*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio");
369*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("audio");
370*d9f75844SAndroid Build Coastguard Worker 
371*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
372*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
373*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
374*d9f75844SAndroid Build Coastguard Worker 
375*d9f75844SAndroid Build Coastguard Worker   // If caller reoffers with no changes expect no additional OnTrack calls.
376*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
377*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
378*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
379*d9f75844SAndroid Build Coastguard Worker 
380*d9f75844SAndroid Build Coastguard Worker   // Also if callee reoffers with no changes expect no additional OnTrack calls.
381*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
382*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
383*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
384*d9f75844SAndroid Build Coastguard Worker }
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker // Test that OnTrack is called when the transceiver direction changes to send
387*d9f75844SAndroid Build Coastguard Worker // the track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,SetDirectionCallsOnTrack)388*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionCallsOnTrack) {
389*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
390*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
391*d9f75844SAndroid Build Coastguard Worker 
392*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
393*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
394*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
395*d9f75844SAndroid Build Coastguard Worker           .ok());
396*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
397*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
398*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->observer()->on_track_transceivers_.size());
399*d9f75844SAndroid Build Coastguard Worker 
400*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
401*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendOnly)
402*d9f75844SAndroid Build Coastguard Worker           .ok());
403*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
404*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
405*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
406*d9f75844SAndroid Build Coastguard Worker 
407*d9f75844SAndroid Build Coastguard Worker   // If the direction changes but it is still receiving on the remote side, then
408*d9f75844SAndroid Build Coastguard Worker   // OnTrack should not be fired again.
409*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
410*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv)
411*d9f75844SAndroid Build Coastguard Worker           .ok());
412*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
413*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
414*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
415*d9f75844SAndroid Build Coastguard Worker }
416*d9f75844SAndroid Build Coastguard Worker 
417*d9f75844SAndroid Build Coastguard Worker // Test that OnTrack is called twice when a sendrecv call is started, the callee
418*d9f75844SAndroid Build Coastguard Worker // changes the direction to inactive, then changes it back to sendrecv.
TEST_F(PeerConnectionRtpTestUnifiedPlan,SetDirectionHoldCallsOnTrackTwice)419*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, SetDirectionHoldCallsOnTrackTwice) {
420*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
421*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
422*d9f75844SAndroid Build Coastguard Worker 
423*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
424*d9f75844SAndroid Build Coastguard Worker 
425*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
426*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
427*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
428*d9f75844SAndroid Build Coastguard Worker 
429*d9f75844SAndroid Build Coastguard Worker   // Put the call on hold by no longer receiving the track.
430*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->pc()
431*d9f75844SAndroid Build Coastguard Worker                   ->GetTransceivers()[0]
432*d9f75844SAndroid Build Coastguard Worker                   ->SetDirectionWithError(RtpTransceiverDirection::kInactive)
433*d9f75844SAndroid Build Coastguard Worker                   .ok());
434*d9f75844SAndroid Build Coastguard Worker 
435*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
436*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
437*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
438*d9f75844SAndroid Build Coastguard Worker 
439*d9f75844SAndroid Build Coastguard Worker   // Resume the call by changing the direction to recvonly. This should call
440*d9f75844SAndroid Build Coastguard Worker   // OnTrack again on the callee side.
441*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->pc()
442*d9f75844SAndroid Build Coastguard Worker                   ->GetTransceivers()[0]
443*d9f75844SAndroid Build Coastguard Worker                   ->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly)
444*d9f75844SAndroid Build Coastguard Worker                   .ok());
445*d9f75844SAndroid Build Coastguard Worker 
446*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
447*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
448*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2u, callee->observer()->on_track_transceivers_.size());
449*d9f75844SAndroid Build Coastguard Worker }
450*d9f75844SAndroid Build Coastguard Worker 
451*d9f75844SAndroid Build Coastguard Worker // Test that setting a remote offer twice with no answer in the middle results
452*d9f75844SAndroid Build Coastguard Worker // in OnAddTrack being fired only once.
TEST_F(PeerConnectionRtpTestUnifiedPlan,ApplyTwoRemoteOffersWithNoAnswerResultsInOneAddTrackEvent)453*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
454*d9f75844SAndroid Build Coastguard Worker        ApplyTwoRemoteOffersWithNoAnswerResultsInOneAddTrackEvent) {
455*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
456*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
457*d9f75844SAndroid Build Coastguard Worker 
458*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track", {});
459*d9f75844SAndroid Build Coastguard Worker 
460*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
461*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
462*d9f75844SAndroid Build Coastguard Worker 
463*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
464*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
465*d9f75844SAndroid Build Coastguard Worker }
466*d9f75844SAndroid Build Coastguard Worker 
467*d9f75844SAndroid Build Coastguard Worker // Test that setting a remote offer twice with no answer in the middle and the
468*d9f75844SAndroid Build Coastguard Worker // track being removed between the two offers results in OnAddTrack being called
469*d9f75844SAndroid Build Coastguard Worker // once the first time and OnRemoveTrack being called once the second time.
TEST_F(PeerConnectionRtpTestUnifiedPlan,ApplyRemoteOfferAddThenRemoteOfferRemoveResultsInOneRemoveTrackEvent)470*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
471*d9f75844SAndroid Build Coastguard Worker        ApplyRemoteOfferAddThenRemoteOfferRemoveResultsInOneRemoveTrackEvent) {
472*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
473*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
474*d9f75844SAndroid Build Coastguard Worker 
475*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {});
476*d9f75844SAndroid Build Coastguard Worker 
477*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
478*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee->observer()->add_track_events_.size());
479*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->observer()->remove_track_events_.size());
480*d9f75844SAndroid Build Coastguard Worker 
481*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(sender);
482*d9f75844SAndroid Build Coastguard Worker 
483*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
484*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
485*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->remove_track_events_.size());
486*d9f75844SAndroid Build Coastguard Worker }
487*d9f75844SAndroid Build Coastguard Worker 
488*d9f75844SAndroid Build Coastguard Worker // Test that changing the direction from receiving to not receiving between
489*d9f75844SAndroid Build Coastguard Worker // setting the remote offer and creating / setting the local answer results in
490*d9f75844SAndroid Build Coastguard Worker // a remove track event when SetLocalDescription is called.
TEST_F(PeerConnectionRtpTestUnifiedPlan,ChangeDirectionInAnswerResultsInRemoveTrackEvent)491*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
492*d9f75844SAndroid Build Coastguard Worker        ChangeDirectionInAnswerResultsInRemoveTrackEvent) {
493*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
494*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
495*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
496*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("audio_track", {});
497*d9f75844SAndroid Build Coastguard Worker 
498*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
499*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
500*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->observer()->remove_track_events_.size());
501*d9f75844SAndroid Build Coastguard Worker 
502*d9f75844SAndroid Build Coastguard Worker   auto callee_transceiver = callee->pc()->GetTransceivers()[0];
503*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_transceiver
504*d9f75844SAndroid Build Coastguard Worker                   ->SetDirectionWithError(RtpTransceiverDirection::kSendOnly)
505*d9f75844SAndroid Build Coastguard Worker                   .ok());
506*d9f75844SAndroid Build Coastguard Worker 
507*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
508*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->add_track_events_.size());
509*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, callee->observer()->remove_track_events_.size());
510*d9f75844SAndroid Build Coastguard Worker }
511*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,ChangeMsidWhileReceiving)512*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, ChangeMsidWhileReceiving) {
513*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
514*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track", {"stream1"});
515*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
516*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
517*d9f75844SAndroid Build Coastguard Worker 
518*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee->observer()->on_track_transceivers_.size());
519*d9f75844SAndroid Build Coastguard Worker   auto transceiver = callee->observer()->on_track_transceivers_[0];
520*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, transceiver->receiver()->streams().size());
521*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("stream1", transceiver->receiver()->streams()[0]->id());
522*d9f75844SAndroid Build Coastguard Worker 
523*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->CreateAnswerAndSetAsLocal());
524*d9f75844SAndroid Build Coastguard Worker 
525*d9f75844SAndroid Build Coastguard Worker   // Change the stream ID in the offer.
526*d9f75844SAndroid Build Coastguard Worker   caller->pc()->GetSenders()[0]->SetStreams({"stream2"});
527*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
528*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, transceiver->receiver()->streams().size());
529*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("stream2", transceiver->receiver()->streams()[0]->id());
530*d9f75844SAndroid Build Coastguard Worker }
531*d9f75844SAndroid Build Coastguard Worker 
532*d9f75844SAndroid Build Coastguard Worker // These tests examine the state of the peer connection as a result of
533*d9f75844SAndroid Build Coastguard Worker // performing SetRemoteDescription().
534*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,AddTrackWithoutStreamAddsReceiver)535*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, AddTrackWithoutStreamAddsReceiver) {
536*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
537*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
538*d9f75844SAndroid Build Coastguard Worker 
539*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("audio_track", {}));
540*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
541*d9f75844SAndroid Build Coastguard Worker 
542*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
543*d9f75844SAndroid Build Coastguard Worker   auto receiver_added = callee->pc()->GetReceivers()[0];
544*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("audio_track", receiver_added->track()->id());
545*d9f75844SAndroid Build Coastguard Worker 
546*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
547*d9f75844SAndroid Build Coastguard Worker     // Since we are not supporting the no stream case with Plan B, there should
548*d9f75844SAndroid Build Coastguard Worker     // be a generated stream, even though we didn't set one with AddTrack.
549*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, receiver_added->streams().size());
550*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
551*d9f75844SAndroid Build Coastguard Worker   } else {
552*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0u, receiver_added->streams().size());
553*d9f75844SAndroid Build Coastguard Worker   }
554*d9f75844SAndroid Build Coastguard Worker }
555*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,AddTrackWithStreamAddsReceiver)556*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, AddTrackWithStreamAddsReceiver) {
557*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
558*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
559*d9f75844SAndroid Build Coastguard Worker 
560*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("audio_track", {"audio_stream"}));
561*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
562*d9f75844SAndroid Build Coastguard Worker 
563*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
564*d9f75844SAndroid Build Coastguard Worker   auto receiver_added = callee->pc()->GetReceivers()[0];
565*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("audio_track", receiver_added->track()->id());
566*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receiver_added->streams().size(), 1u);
567*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("audio_stream", receiver_added->streams()[0]->id());
568*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
569*d9f75844SAndroid Build Coastguard Worker }
570*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithoutStreamRemovesReceiver)571*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithoutStreamRemovesReceiver) {
572*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
573*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
574*d9f75844SAndroid Build Coastguard Worker 
575*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {});
576*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
577*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
578*d9f75844SAndroid Build Coastguard Worker 
579*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
580*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee->pc()->GetReceivers()[0];
581*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
582*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
583*d9f75844SAndroid Build Coastguard Worker 
584*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
585*d9f75844SAndroid Build Coastguard Worker     // With Unified Plan the receiver stays but the transceiver transitions to
586*d9f75844SAndroid Build Coastguard Worker     // inactive.
587*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
588*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(RtpTransceiverDirection::kInactive,
589*d9f75844SAndroid Build Coastguard Worker               callee->pc()->GetTransceivers()[0]->current_direction());
590*d9f75844SAndroid Build Coastguard Worker   } else {
591*d9f75844SAndroid Build Coastguard Worker     // With Plan B the receiver is removed.
592*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
593*d9f75844SAndroid Build Coastguard Worker   }
594*d9f75844SAndroid Build Coastguard Worker }
595*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithStreamRemovesReceiver)596*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithStreamRemovesReceiver) {
597*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
598*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
599*d9f75844SAndroid Build Coastguard Worker 
600*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {"audio_stream"});
601*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
602*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
603*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
604*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee->pc()->GetReceivers()[0];
605*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
606*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
607*d9f75844SAndroid Build Coastguard Worker 
608*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
609*d9f75844SAndroid Build Coastguard Worker     // With Unified Plan the receiver stays but the transceiver transitions to
610*d9f75844SAndroid Build Coastguard Worker     // inactive.
611*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(1u, callee->pc()->GetReceivers().size());
612*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(RtpTransceiverDirection::kInactive,
613*d9f75844SAndroid Build Coastguard Worker               callee->pc()->GetTransceivers()[0]->current_direction());
614*d9f75844SAndroid Build Coastguard Worker   } else {
615*d9f75844SAndroid Build Coastguard Worker     // With Plan B the receiver is removed.
616*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
617*d9f75844SAndroid Build Coastguard Worker   }
618*d9f75844SAndroid Build Coastguard Worker }
619*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,RemoveTrackWithSharedStreamRemovesReceiver)620*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamRemovesReceiver) {
621*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
622*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
623*d9f75844SAndroid Build Coastguard Worker 
624*d9f75844SAndroid Build Coastguard Worker   const char kSharedStreamId[] = "shared_audio_stream";
625*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddAudioTrack("audio_track1", {kSharedStreamId});
626*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddAudioTrack("audio_track2", {kSharedStreamId});
627*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
628*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
629*d9f75844SAndroid Build Coastguard Worker 
630*d9f75844SAndroid Build Coastguard Worker   // Remove "audio_track1".
631*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender1).ok());
632*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
633*d9f75844SAndroid Build Coastguard Worker 
634*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
635*d9f75844SAndroid Build Coastguard Worker     // With Unified Plan the receiver stays but the transceiver transitions to
636*d9f75844SAndroid Build Coastguard Worker     // inactive.
637*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
638*d9f75844SAndroid Build Coastguard Worker     auto transceiver = callee->pc()->GetTransceivers()[0];
639*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ("audio_track1", transceiver->receiver()->track()->id());
640*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(RtpTransceiverDirection::kInactive,
641*d9f75844SAndroid Build Coastguard Worker               transceiver->current_direction());
642*d9f75844SAndroid Build Coastguard Worker   } else {
643*d9f75844SAndroid Build Coastguard Worker     // With Plan B the receiver is removed.
644*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, callee->pc()->GetReceivers().size());
645*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ("audio_track2", callee->pc()->GetReceivers()[0]->track()->id());
646*d9f75844SAndroid Build Coastguard Worker   }
647*d9f75844SAndroid Build Coastguard Worker 
648*d9f75844SAndroid Build Coastguard Worker   // Remove "audio_track2".
649*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender2).ok());
650*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
651*d9f75844SAndroid Build Coastguard Worker 
652*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
653*d9f75844SAndroid Build Coastguard Worker     // With Unified Plan the receiver stays but the transceiver transitions to
654*d9f75844SAndroid Build Coastguard Worker     // inactive.
655*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(2u, callee->pc()->GetReceivers().size());
656*d9f75844SAndroid Build Coastguard Worker     auto transceiver = callee->pc()->GetTransceivers()[1];
657*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ("audio_track2", transceiver->receiver()->track()->id());
658*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(RtpTransceiverDirection::kInactive,
659*d9f75844SAndroid Build Coastguard Worker               transceiver->current_direction());
660*d9f75844SAndroid Build Coastguard Worker   } else {
661*d9f75844SAndroid Build Coastguard Worker     // With Plan B the receiver is removed.
662*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(0u, callee->pc()->GetReceivers().size());
663*d9f75844SAndroid Build Coastguard Worker   }
664*d9f75844SAndroid Build Coastguard Worker }
665*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,AudioGetParametersHasHeaderExtensions)666*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, AudioGetParametersHasHeaderExtensions) {
667*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
668*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
669*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track");
670*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
671*d9f75844SAndroid Build Coastguard Worker 
672*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(caller->pc()->GetSenders().size(), 0u);
673*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u);
674*d9f75844SAndroid Build Coastguard Worker 
675*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(callee->pc()->GetReceivers().size(), 0u);
676*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee->pc()->GetReceivers()[0];
677*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u);
678*d9f75844SAndroid Build Coastguard Worker }
679*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,VideoGetParametersHasHeaderExtensions)680*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, VideoGetParametersHasHeaderExtensions) {
681*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
682*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
683*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddVideoTrack("video_track");
684*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
685*d9f75844SAndroid Build Coastguard Worker 
686*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(caller->pc()->GetSenders().size(), 0u);
687*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u);
688*d9f75844SAndroid Build Coastguard Worker 
689*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(callee->pc()->GetReceivers().size(), 0u);
690*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee->pc()->GetReceivers()[0];
691*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u);
692*d9f75844SAndroid Build Coastguard Worker }
693*d9f75844SAndroid Build Coastguard Worker 
694*d9f75844SAndroid Build Coastguard Worker // Invokes SetRemoteDescription() twice in a row without synchronizing the two
695*d9f75844SAndroid Build Coastguard Worker // calls and examine the state of the peer connection inside the callbacks to
696*d9f75844SAndroid Build Coastguard Worker // ensure that the second call does not occur prematurely, contaminating the
697*d9f75844SAndroid Build Coastguard Worker // state of the peer connection of the first callback.
TEST_F(PeerConnectionRtpTestPlanB,StatesCorrelateWithSetRemoteDescriptionCall)698*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestPlanB,
699*d9f75844SAndroid Build Coastguard Worker        StatesCorrelateWithSetRemoteDescriptionCall) {
700*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
701*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
702*d9f75844SAndroid Build Coastguard Worker 
703*d9f75844SAndroid Build Coastguard Worker   // Create SDP for adding a track and for removing it. This will be used in the
704*d9f75844SAndroid Build Coastguard Worker   // first and second SetRemoteDescription() calls.
705*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("audio_track", {});
706*d9f75844SAndroid Build Coastguard Worker   auto srd1_sdp = caller->CreateOfferAndSetAsLocal();
707*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
708*d9f75844SAndroid Build Coastguard Worker   auto srd2_sdp = caller->CreateOfferAndSetAsLocal();
709*d9f75844SAndroid Build Coastguard Worker 
710*d9f75844SAndroid Build Coastguard Worker   // In the first SetRemoteDescription() callback, check that we have a
711*d9f75844SAndroid Build Coastguard Worker   // receiver for the track.
712*d9f75844SAndroid Build Coastguard Worker   auto pc = callee->pc();
713*d9f75844SAndroid Build Coastguard Worker   bool srd1_callback_called = false;
714*d9f75844SAndroid Build Coastguard Worker   auto srd1_callback = [&srd1_callback_called, &pc]() {
715*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(pc->GetReceivers().size(), 1u);
716*d9f75844SAndroid Build Coastguard Worker     srd1_callback_called = true;
717*d9f75844SAndroid Build Coastguard Worker   };
718*d9f75844SAndroid Build Coastguard Worker 
719*d9f75844SAndroid Build Coastguard Worker   // In the second SetRemoteDescription() callback, check that the receiver has
720*d9f75844SAndroid Build Coastguard Worker   // been removed.
721*d9f75844SAndroid Build Coastguard Worker   // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
722*d9f75844SAndroid Build Coastguard Worker   // Instead, the transceiver owning the receiver will become inactive.
723*d9f75844SAndroid Build Coastguard Worker   // https://crbug.com/webrtc/7600
724*d9f75844SAndroid Build Coastguard Worker   bool srd2_callback_called = false;
725*d9f75844SAndroid Build Coastguard Worker   auto srd2_callback = [&srd2_callback_called, &pc]() {
726*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(pc->GetReceivers().empty());
727*d9f75844SAndroid Build Coastguard Worker     srd2_callback_called = true;
728*d9f75844SAndroid Build Coastguard Worker   };
729*d9f75844SAndroid Build Coastguard Worker 
730*d9f75844SAndroid Build Coastguard Worker   // Invoke SetRemoteDescription() twice in a row without synchronizing the two
731*d9f75844SAndroid Build Coastguard Worker   // calls. The callbacks verify that the two calls are synchronized, as in, the
732*d9f75844SAndroid Build Coastguard Worker   // effects of the second SetRemoteDescription() call must not have happened by
733*d9f75844SAndroid Build Coastguard Worker   // the time the first callback is invoked. If it has then the receiver that is
734*d9f75844SAndroid Build Coastguard Worker   // added as a result of the first SetRemoteDescription() call will already
735*d9f75844SAndroid Build Coastguard Worker   // have been removed as a result of the second SetRemoteDescription() call
736*d9f75844SAndroid Build Coastguard Worker   // when the first callback is invoked.
737*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(
738*d9f75844SAndroid Build Coastguard Worker       std::move(srd1_sdp),
739*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<OnSuccessObserver<decltype(srd1_callback)>>(
740*d9f75844SAndroid Build Coastguard Worker           srd1_callback));
741*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(
742*d9f75844SAndroid Build Coastguard Worker       std::move(srd2_sdp),
743*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<OnSuccessObserver<decltype(srd2_callback)>>(
744*d9f75844SAndroid Build Coastguard Worker           srd2_callback));
745*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(srd1_callback_called, kDefaultTimeout);
746*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(srd2_callback_called, kDefaultTimeout);
747*d9f75844SAndroid Build Coastguard Worker }
748*d9f75844SAndroid Build Coastguard Worker 
749*d9f75844SAndroid Build Coastguard Worker // Tests that a remote track is created with the signaled MSIDs when they are
750*d9f75844SAndroid Build Coastguard Worker // communicated with a=msid and no SSRCs are signaled at all (i.e., no a=ssrc
751*d9f75844SAndroid Build Coastguard Worker // lines).
TEST_F(PeerConnectionRtpTestUnifiedPlan,UnsignaledSsrcCreatesReceiverStreams)752*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, UnsignaledSsrcCreatesReceiverStreams) {
753*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
754*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
755*d9f75844SAndroid Build Coastguard Worker   const char kStreamId1[] = "stream1";
756*d9f75844SAndroid Build Coastguard Worker   const char kStreamId2[] = "stream2";
757*d9f75844SAndroid Build Coastguard Worker   caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
758*d9f75844SAndroid Build Coastguard Worker                    {kStreamId1, kStreamId2});
759*d9f75844SAndroid Build Coastguard Worker 
760*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
761*d9f75844SAndroid Build Coastguard Worker   // Munge the offer to take out everything but the stream_ids.
762*d9f75844SAndroid Build Coastguard Worker   auto contents = offer->description()->contents();
763*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(!contents.empty());
764*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(!contents[0].media_description()->streams().empty());
765*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> stream_ids =
766*d9f75844SAndroid Build Coastguard Worker       contents[0].media_description()->streams()[0].stream_ids();
767*d9f75844SAndroid Build Coastguard Worker   contents[0].media_description()->mutable_streams().clear();
768*d9f75844SAndroid Build Coastguard Worker   cricket::StreamParams new_stream;
769*d9f75844SAndroid Build Coastguard Worker   new_stream.set_stream_ids(stream_ids);
770*d9f75844SAndroid Build Coastguard Worker   contents[0].media_description()->AddStream(new_stream);
771*d9f75844SAndroid Build Coastguard Worker 
772*d9f75844SAndroid Build Coastguard Worker   // Set the remote description and verify that the streams were added to the
773*d9f75844SAndroid Build Coastguard Worker   // receiver correctly.
774*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
775*d9f75844SAndroid Build Coastguard Worker       callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
776*d9f75844SAndroid Build Coastguard Worker   auto receivers = callee->pc()->GetReceivers();
777*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers.size(), 1u);
778*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers[0]->streams().size(), 2u);
779*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId1);
780*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[0]->streams()[1]->id(), kStreamId2);
781*d9f75844SAndroid Build Coastguard Worker }
TEST_F(PeerConnectionRtpTestUnifiedPlan,TracksDoNotEndWhenSsrcChanges)782*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, TracksDoNotEndWhenSsrcChanges) {
783*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t kFirstMungedSsrc = 1337u;
784*d9f75844SAndroid Build Coastguard Worker 
785*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
786*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
787*d9f75844SAndroid Build Coastguard Worker 
788*d9f75844SAndroid Build Coastguard Worker   // Caller offers to receive audio and video.
789*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
790*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kRecvOnly;
791*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
792*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
793*d9f75844SAndroid Build Coastguard Worker 
794*d9f75844SAndroid Build Coastguard Worker   // Callee wants to send audio and video tracks.
795*d9f75844SAndroid Build Coastguard Worker   callee->AddTrack(callee->CreateAudioTrack("audio_track"), {});
796*d9f75844SAndroid Build Coastguard Worker   callee->AddTrack(callee->CreateVideoTrack("video_track"), {});
797*d9f75844SAndroid Build Coastguard Worker 
798*d9f75844SAndroid Build Coastguard Worker   // Do inittial offer/answer exchange.
799*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
800*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
801*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
802*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(caller->observer()->add_track_events_.size(), 2u);
803*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(caller->pc()->GetReceivers().size(), 2u);
804*d9f75844SAndroid Build Coastguard Worker 
805*d9f75844SAndroid Build Coastguard Worker   // Do a follow-up offer/answer exchange where the SSRCs are modified.
806*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
807*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
808*d9f75844SAndroid Build Coastguard Worker   auto& contents = answer->description()->contents();
809*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(!contents.empty());
810*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < contents.size(); ++i) {
811*d9f75844SAndroid Build Coastguard Worker     auto& mutable_streams = contents[i].media_description()->mutable_streams();
812*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(mutable_streams.size(), 1u);
813*d9f75844SAndroid Build Coastguard Worker     mutable_streams[0].ssrcs = {kFirstMungedSsrc + static_cast<uint32_t>(i)};
814*d9f75844SAndroid Build Coastguard Worker   }
815*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
816*d9f75844SAndroid Build Coastguard Worker       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
817*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
818*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(CloneSessionDescription(answer.get())));
819*d9f75844SAndroid Build Coastguard Worker 
820*d9f75844SAndroid Build Coastguard Worker   // No furher track events should fire because we never changed direction, only
821*d9f75844SAndroid Build Coastguard Worker   // SSRCs.
822*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(caller->observer()->add_track_events_.size(), 2u);
823*d9f75844SAndroid Build Coastguard Worker   // We should have the same number of receivers as before.
824*d9f75844SAndroid Build Coastguard Worker   auto receivers = caller->pc()->GetReceivers();
825*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers.size(), 2u);
826*d9f75844SAndroid Build Coastguard Worker   // The tracks are still alive.
827*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[0]->track()->state(),
828*d9f75844SAndroid Build Coastguard Worker             MediaStreamTrackInterface::TrackState::kLive);
829*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[1]->track()->state(),
830*d9f75844SAndroid Build Coastguard Worker             MediaStreamTrackInterface::TrackState::kLive);
831*d9f75844SAndroid Build Coastguard Worker }
832*d9f75844SAndroid Build Coastguard Worker 
833*d9f75844SAndroid Build Coastguard Worker // Tests that with Unified Plan if the the stream id changes for a track when
834*d9f75844SAndroid Build Coastguard Worker // when setting a new remote description, that the media stream is updated
835*d9f75844SAndroid Build Coastguard Worker // appropriately for the receiver.
836*d9f75844SAndroid Build Coastguard Worker // TODO(https://github.com/w3c/webrtc-pc/issues/1937): Resolve spec issue or fix
837*d9f75844SAndroid Build Coastguard Worker // test.
TEST_F(PeerConnectionRtpTestUnifiedPlan,DISABLED_RemoteStreamIdChangesUpdatesReceiver)838*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
839*d9f75844SAndroid Build Coastguard Worker        DISABLED_RemoteStreamIdChangesUpdatesReceiver) {
840*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
841*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
842*d9f75844SAndroid Build Coastguard Worker 
843*d9f75844SAndroid Build Coastguard Worker   const char kStreamId1[] = "stream1";
844*d9f75844SAndroid Build Coastguard Worker   const char kStreamId2[] = "stream2";
845*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track1", {kStreamId1});
846*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
847*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
848*d9f75844SAndroid Build Coastguard Worker 
849*d9f75844SAndroid Build Coastguard Worker   // Change the stream id of the sender in the session description.
850*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
851*d9f75844SAndroid Build Coastguard Worker   auto contents = offer->description()->contents();
852*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(contents.size(), 1u);
853*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(contents[0].media_description()->mutable_streams().size(), 1u);
854*d9f75844SAndroid Build Coastguard Worker   contents[0].media_description()->mutable_streams()[0].set_stream_ids(
855*d9f75844SAndroid Build Coastguard Worker       {kStreamId2});
856*d9f75844SAndroid Build Coastguard Worker 
857*d9f75844SAndroid Build Coastguard Worker   // Set the remote description and verify that the stream was updated
858*d9f75844SAndroid Build Coastguard Worker   // properly.
859*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
860*d9f75844SAndroid Build Coastguard Worker   auto receivers = callee->pc()->GetReceivers();
861*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers.size(), 1u);
862*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers[0]->streams().size(), 1u);
863*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId2);
864*d9f75844SAndroid Build Coastguard Worker }
865*d9f75844SAndroid Build Coastguard Worker 
866*d9f75844SAndroid Build Coastguard Worker // This tests a regression caught by a downstream client, that occured when
867*d9f75844SAndroid Build Coastguard Worker // applying a remote description with a SessionDescription object that
868*d9f75844SAndroid Build Coastguard Worker // contained StreamParams that didn't have ids. Although there were multiple
869*d9f75844SAndroid Build Coastguard Worker // remote audio senders, FindSenderInfo didn't find them as unique, because
870*d9f75844SAndroid Build Coastguard Worker // it looked up by StreamParam.id, which none had. This meant only one
871*d9f75844SAndroid Build Coastguard Worker // AudioRtpReceiver was created, as opposed to one for each remote sender.
TEST_F(PeerConnectionRtpTestPlanB,MultipleRemoteSendersWithoutStreamParamIdAddsMultipleReceivers)872*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestPlanB,
873*d9f75844SAndroid Build Coastguard Worker        MultipleRemoteSendersWithoutStreamParamIdAddsMultipleReceivers) {
874*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
875*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
876*d9f75844SAndroid Build Coastguard Worker 
877*d9f75844SAndroid Build Coastguard Worker   const char kStreamId1[] = "stream1";
878*d9f75844SAndroid Build Coastguard Worker   const char kStreamId2[] = "stream2";
879*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track1", {kStreamId1});
880*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("audio_track2", {kStreamId2});
881*d9f75844SAndroid Build Coastguard Worker 
882*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
883*d9f75844SAndroid Build Coastguard Worker   auto mutable_streams =
884*d9f75844SAndroid Build Coastguard Worker       cricket::GetFirstAudioContentDescription(offer->description())
885*d9f75844SAndroid Build Coastguard Worker           ->mutable_streams();
886*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(mutable_streams.size(), 2u);
887*d9f75844SAndroid Build Coastguard Worker   // Clear the IDs in the StreamParams.
888*d9f75844SAndroid Build Coastguard Worker   mutable_streams[0].id.clear();
889*d9f75844SAndroid Build Coastguard Worker   mutable_streams[1].id.clear();
890*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
891*d9f75844SAndroid Build Coastguard Worker       callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
892*d9f75844SAndroid Build Coastguard Worker 
893*d9f75844SAndroid Build Coastguard Worker   auto receivers = callee->pc()->GetReceivers();
894*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers.size(), 2u);
895*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers[0]->streams().size(), 1u);
896*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kStreamId1, receivers[0]->streams()[0]->id());
897*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receivers[1]->streams().size(), 1u);
898*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kStreamId2, receivers[1]->streams()[0]->id());
899*d9f75844SAndroid Build Coastguard Worker }
900*d9f75844SAndroid Build Coastguard Worker 
901*d9f75844SAndroid Build Coastguard Worker // Tests for the legacy SetRemoteDescription() function signature.
902*d9f75844SAndroid Build Coastguard Worker 
903*d9f75844SAndroid Build Coastguard Worker // Sanity test making sure the callback is invoked.
TEST_P(PeerConnectionRtpTest,LegacyObserverOnSuccess)904*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, LegacyObserverOnSuccess) {
905*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
906*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
907*d9f75844SAndroid Build Coastguard Worker 
908*d9f75844SAndroid Build Coastguard Worker   std::string error;
909*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
910*d9f75844SAndroid Build Coastguard Worker       callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal(), &error));
911*d9f75844SAndroid Build Coastguard Worker }
912*d9f75844SAndroid Build Coastguard Worker 
913*d9f75844SAndroid Build Coastguard Worker // Verifies legacy behavior: The observer is not called if if the peer
914*d9f75844SAndroid Build Coastguard Worker // connection is destroyed because the asynchronous callback is executed in the
915*d9f75844SAndroid Build Coastguard Worker // peer connection's message handler.
TEST_P(PeerConnectionRtpTest,LegacyObserverNotCalledIfPeerConnectionDereferenced)916*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest,
917*d9f75844SAndroid Build Coastguard Worker        LegacyObserverNotCalledIfPeerConnectionDereferenced) {
918*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
919*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
920*d9f75844SAndroid Build Coastguard Worker 
921*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::MockSetSessionDescriptionObserver> observer =
922*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<webrtc::MockSetSessionDescriptionObserver>();
923*d9f75844SAndroid Build Coastguard Worker 
924*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
925*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(observer.get(), offer.release());
926*d9f75844SAndroid Build Coastguard Worker   callee = nullptr;
927*d9f75844SAndroid Build Coastguard Worker   rtc::Thread::Current()->ProcessMessages(0);
928*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
929*d9f75844SAndroid Build Coastguard Worker }
930*d9f75844SAndroid Build Coastguard Worker 
931*d9f75844SAndroid Build Coastguard Worker // RtpTransceiver Tests.
932*d9f75844SAndroid Build Coastguard Worker 
933*d9f75844SAndroid Build Coastguard Worker // Test that by default there are no transceivers with Unified Plan.
TEST_F(PeerConnectionRtpTestUnifiedPlan,PeerConnectionHasNoTransceivers)934*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, PeerConnectionHasNoTransceivers) {
935*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
936*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(caller->pc()->GetTransceivers(), ElementsAre());
937*d9f75844SAndroid Build Coastguard Worker }
938*d9f75844SAndroid Build Coastguard Worker 
939*d9f75844SAndroid Build Coastguard Worker // Test that a transceiver created with the audio kind has the correct initial
940*d9f75844SAndroid Build Coastguard Worker // properties.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverHasCorrectInitProperties)941*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
942*d9f75844SAndroid Build Coastguard Worker        AddTransceiverHasCorrectInitProperties) {
943*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
944*d9f75844SAndroid Build Coastguard Worker 
945*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
946*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(absl::nullopt, transceiver->mid());
947*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(transceiver->stopped());
948*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
949*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(absl::nullopt, transceiver->current_direction());
950*d9f75844SAndroid Build Coastguard Worker }
951*d9f75844SAndroid Build Coastguard Worker 
952*d9f75844SAndroid Build Coastguard Worker // Test that adding a transceiver with the audio kind creates an audio sender
953*d9f75844SAndroid Build Coastguard Worker // and audio receiver with the receiver having a live audio track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddAudioTransceiverCreatesAudioSenderAndReceiver)954*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
955*d9f75844SAndroid Build Coastguard Worker        AddAudioTransceiverCreatesAudioSenderAndReceiver) {
956*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
957*d9f75844SAndroid Build Coastguard Worker 
958*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
959*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->media_type());
960*d9f75844SAndroid Build Coastguard Worker 
961*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(transceiver->sender());
962*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->sender()->media_type());
963*d9f75844SAndroid Build Coastguard Worker 
964*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(transceiver->receiver());
965*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->receiver()->media_type());
966*d9f75844SAndroid Build Coastguard Worker 
967*d9f75844SAndroid Build Coastguard Worker   auto track = transceiver->receiver()->track();
968*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(track);
969*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, track->kind());
970*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
971*d9f75844SAndroid Build Coastguard Worker }
972*d9f75844SAndroid Build Coastguard Worker 
973*d9f75844SAndroid Build Coastguard Worker // Test that adding a transceiver with the video kind creates an video sender
974*d9f75844SAndroid Build Coastguard Worker // and video receiver with the receiver having a live video track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddAudioTransceiverCreatesVideoSenderAndReceiver)975*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
976*d9f75844SAndroid Build Coastguard Worker        AddAudioTransceiverCreatesVideoSenderAndReceiver) {
977*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
978*d9f75844SAndroid Build Coastguard Worker 
979*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
980*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
981*d9f75844SAndroid Build Coastguard Worker 
982*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(transceiver->sender());
983*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->sender()->media_type());
984*d9f75844SAndroid Build Coastguard Worker 
985*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(transceiver->receiver());
986*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->receiver()->media_type());
987*d9f75844SAndroid Build Coastguard Worker 
988*d9f75844SAndroid Build Coastguard Worker   auto track = transceiver->receiver()->track();
989*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(track);
990*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::kVideoKind, track->kind());
991*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
992*d9f75844SAndroid Build Coastguard Worker }
993*d9f75844SAndroid Build Coastguard Worker 
994*d9f75844SAndroid Build Coastguard Worker // Test that after a call to AddTransceiver, the transceiver shows in
995*d9f75844SAndroid Build Coastguard Worker // GetTransceivers(), the transceiver's sender shows in GetSenders(), and the
996*d9f75844SAndroid Build Coastguard Worker // transceiver's receiver shows in GetReceivers().
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverShowsInLists)997*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTransceiverShowsInLists) {
998*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
999*d9f75844SAndroid Build Coastguard Worker 
1000*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1001*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1002*d9f75844SAndroid Build Coastguard Worker       std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>{transceiver},
1003*d9f75844SAndroid Build Coastguard Worker       caller->pc()->GetTransceivers());
1004*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1005*d9f75844SAndroid Build Coastguard Worker       std::vector<rtc::scoped_refptr<RtpSenderInterface>>{
1006*d9f75844SAndroid Build Coastguard Worker           transceiver->sender()},
1007*d9f75844SAndroid Build Coastguard Worker       caller->pc()->GetSenders());
1008*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1009*d9f75844SAndroid Build Coastguard Worker       std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
1010*d9f75844SAndroid Build Coastguard Worker           transceiver->receiver()},
1011*d9f75844SAndroid Build Coastguard Worker       caller->pc()->GetReceivers());
1012*d9f75844SAndroid Build Coastguard Worker }
1013*d9f75844SAndroid Build Coastguard Worker 
1014*d9f75844SAndroid Build Coastguard Worker // Test that the direction passed in through the AddTransceiver init parameter
1015*d9f75844SAndroid Build Coastguard Worker // is set in the returned transceiver.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverWithDirectionIsReflected)1016*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1017*d9f75844SAndroid Build Coastguard Worker        AddTransceiverWithDirectionIsReflected) {
1018*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1019*d9f75844SAndroid Build Coastguard Worker 
1020*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1021*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kSendOnly;
1022*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1023*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
1024*d9f75844SAndroid Build Coastguard Worker }
1025*d9f75844SAndroid Build Coastguard Worker 
1026*d9f75844SAndroid Build Coastguard Worker // Test that calling AddTransceiver with a track creates a transceiver which has
1027*d9f75844SAndroid Build Coastguard Worker // its sender's track set to the passed-in track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverWithTrackCreatesSenderWithTrack)1028*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1029*d9f75844SAndroid Build Coastguard Worker        AddTransceiverWithTrackCreatesSenderWithTrack) {
1030*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1031*d9f75844SAndroid Build Coastguard Worker 
1032*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("audio track");
1033*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(audio_track);
1034*d9f75844SAndroid Build Coastguard Worker 
1035*d9f75844SAndroid Build Coastguard Worker   auto sender = transceiver->sender();
1036*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->track());
1037*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender->track());
1038*d9f75844SAndroid Build Coastguard Worker 
1039*d9f75844SAndroid Build Coastguard Worker   auto receiver = transceiver->receiver();
1040*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(receiver->track());
1041*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, receiver->track()->kind());
1042*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive,
1043*d9f75844SAndroid Build Coastguard Worker             receiver->track()->state());
1044*d9f75844SAndroid Build Coastguard Worker }
1045*d9f75844SAndroid Build Coastguard Worker 
1046*d9f75844SAndroid Build Coastguard Worker // Test that calling AddTransceiver twice with the same track creates distinct
1047*d9f75844SAndroid Build Coastguard Worker // transceivers, senders with the same track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverTwiceWithSameTrackCreatesMultipleTransceivers)1048*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1049*d9f75844SAndroid Build Coastguard Worker        AddTransceiverTwiceWithSameTrackCreatesMultipleTransceivers) {
1050*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1051*d9f75844SAndroid Build Coastguard Worker 
1052*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("audio track");
1053*d9f75844SAndroid Build Coastguard Worker 
1054*d9f75844SAndroid Build Coastguard Worker   auto transceiver1 = caller->AddTransceiver(audio_track);
1055*d9f75844SAndroid Build Coastguard Worker   auto transceiver2 = caller->AddTransceiver(audio_track);
1056*d9f75844SAndroid Build Coastguard Worker 
1057*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(transceiver1, transceiver2);
1058*d9f75844SAndroid Build Coastguard Worker 
1059*d9f75844SAndroid Build Coastguard Worker   auto sender1 = transceiver1->sender();
1060*d9f75844SAndroid Build Coastguard Worker   auto sender2 = transceiver2->sender();
1061*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender1, sender2);
1062*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender1->track());
1063*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender2->track());
1064*d9f75844SAndroid Build Coastguard Worker 
1065*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(caller->pc()->GetTransceivers(),
1066*d9f75844SAndroid Build Coastguard Worker               UnorderedElementsAre(transceiver1, transceiver2));
1067*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(caller->pc()->GetSenders(),
1068*d9f75844SAndroid Build Coastguard Worker               UnorderedElementsAre(sender1, sender2));
1069*d9f75844SAndroid Build Coastguard Worker }
1070*d9f75844SAndroid Build Coastguard Worker 
1071*d9f75844SAndroid Build Coastguard Worker // RtpTransceiver error handling tests.
1072*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTransceiverWithInvalidKindReturnsError)1073*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1074*d9f75844SAndroid Build Coastguard Worker        AddTransceiverWithInvalidKindReturnsError) {
1075*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1076*d9f75844SAndroid Build Coastguard Worker 
1077*d9f75844SAndroid Build Coastguard Worker   auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_DATA);
1078*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
1079*d9f75844SAndroid Build Coastguard Worker }
1080*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,CanClosePeerConnectionWithoutCrashing)1081*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1082*d9f75844SAndroid Build Coastguard Worker        CanClosePeerConnectionWithoutCrashing) {
1083*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1084*d9f75844SAndroid Build Coastguard Worker 
1085*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
1086*d9f75844SAndroid Build Coastguard Worker }
1087*d9f75844SAndroid Build Coastguard Worker 
1088*d9f75844SAndroid Build Coastguard Worker // Unified Plan AddTrack tests.
1089*d9f75844SAndroid Build Coastguard Worker 
1090*d9f75844SAndroid Build Coastguard Worker // Test that adding an audio track creates a new audio RtpSender with the given
1091*d9f75844SAndroid Build Coastguard Worker // track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddAudioTrackCreatesAudioSender)1092*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddAudioTrackCreatesAudioSender) {
1093*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1094*d9f75844SAndroid Build Coastguard Worker 
1095*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("a");
1096*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddTrack(audio_track);
1097*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
1098*d9f75844SAndroid Build Coastguard Worker 
1099*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, sender->media_type());
1100*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender->track());
1101*d9f75844SAndroid Build Coastguard Worker }
1102*d9f75844SAndroid Build Coastguard Worker 
1103*d9f75844SAndroid Build Coastguard Worker // Test that adding a video track creates a new video RtpSender with the given
1104*d9f75844SAndroid Build Coastguard Worker // track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddVideoTrackCreatesVideoSender)1105*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddVideoTrackCreatesVideoSender) {
1106*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1107*d9f75844SAndroid Build Coastguard Worker 
1108*d9f75844SAndroid Build Coastguard Worker   auto video_track = caller->CreateVideoTrack("a");
1109*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddTrack(video_track);
1110*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
1111*d9f75844SAndroid Build Coastguard Worker 
1112*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
1113*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(video_track, sender->track());
1114*d9f75844SAndroid Build Coastguard Worker }
1115*d9f75844SAndroid Build Coastguard Worker 
1116*d9f75844SAndroid Build Coastguard Worker // Test that adding a track to a new PeerConnection creates an RtpTransceiver
1117*d9f75844SAndroid Build Coastguard Worker // with the sender that AddTrack returns and in the sendrecv direction.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddFirstTrackCreatesTransceiver)1118*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddFirstTrackCreatesTransceiver) {
1119*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1120*d9f75844SAndroid Build Coastguard Worker 
1121*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1122*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
1123*d9f75844SAndroid Build Coastguard Worker 
1124*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1125*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, transceivers.size());
1126*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender, transceivers[0]->sender());
1127*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceivers[0]->direction());
1128*d9f75844SAndroid Build Coastguard Worker }
1129*d9f75844SAndroid Build Coastguard Worker 
1130*d9f75844SAndroid Build Coastguard Worker // Test that if a transceiver of the same type but no track had been added to
1131*d9f75844SAndroid Build Coastguard Worker // the PeerConnection and later a call to AddTrack is made, the resulting sender
1132*d9f75844SAndroid Build Coastguard Worker // is the transceiver's sender and the sender's track is the newly-added track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackReusesTransceiver)1133*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiver) {
1134*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1135*d9f75844SAndroid Build Coastguard Worker 
1136*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1137*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("a");
1138*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddTrack(audio_track);
1139*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
1140*d9f75844SAndroid Build Coastguard Worker 
1141*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1142*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, transceivers.size());
1143*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver, transceivers[0]);
1144*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender, transceiver->sender());
1145*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender->track());
1146*d9f75844SAndroid Build Coastguard Worker }
1147*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackWithSendEncodingDoesNotReuseTransceiver)1148*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1149*d9f75844SAndroid Build Coastguard Worker        AddTrackWithSendEncodingDoesNotReuseTransceiver) {
1150*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1151*d9f75844SAndroid Build Coastguard Worker 
1152*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1153*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("a");
1154*d9f75844SAndroid Build Coastguard Worker   RtpEncodingParameters encoding;
1155*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddTrack(audio_track, {}, {encoding});
1156*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender);
1157*d9f75844SAndroid Build Coastguard Worker 
1158*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1159*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, transceivers.size());
1160*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(transceiver, transceivers[0]);
1161*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender, transceiver->sender());
1162*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_track, sender->track());
1163*d9f75844SAndroid Build Coastguard Worker }
1164*d9f75844SAndroid Build Coastguard Worker 
1165*d9f75844SAndroid Build Coastguard Worker // Test that adding two tracks to a new PeerConnection creates two
1166*d9f75844SAndroid Build Coastguard Worker // RtpTransceivers in the same order.
TEST_F(PeerConnectionRtpTestUnifiedPlan,TwoAddTrackCreatesTwoTransceivers)1167*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, TwoAddTrackCreatesTwoTransceivers) {
1168*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1169*d9f75844SAndroid Build Coastguard Worker 
1170*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddAudioTrack("a");
1171*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddVideoTrack("v");
1172*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender2);
1173*d9f75844SAndroid Build Coastguard Worker 
1174*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1175*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, transceivers.size());
1176*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender1, transceivers[0]->sender());
1177*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender2, transceivers[1]->sender());
1178*d9f75844SAndroid Build Coastguard Worker }
1179*d9f75844SAndroid Build Coastguard Worker 
1180*d9f75844SAndroid Build Coastguard Worker // Test that if there are multiple transceivers with no sending track then a
1181*d9f75844SAndroid Build Coastguard Worker // later call to AddTrack will use the one of the same type as the newly-added
1182*d9f75844SAndroid Build Coastguard Worker // track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackReusesTransceiverOfType)1183*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackReusesTransceiverOfType) {
1184*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1185*d9f75844SAndroid Build Coastguard Worker 
1186*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1187*d9f75844SAndroid Build Coastguard Worker   auto video_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
1188*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddVideoTrack("v");
1189*d9f75844SAndroid Build Coastguard Worker 
1190*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, caller->pc()->GetTransceivers().size());
1191*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender, audio_transceiver->sender());
1192*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender, video_transceiver->sender());
1193*d9f75844SAndroid Build Coastguard Worker }
1194*d9f75844SAndroid Build Coastguard Worker 
1195*d9f75844SAndroid Build Coastguard Worker // Test that if the only transceivers that do not have a sending track have a
1196*d9f75844SAndroid Build Coastguard Worker // different type from the added track, then AddTrack will create a new
1197*d9f75844SAndroid Build Coastguard Worker // transceiver for the track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackDoesNotReuseTransceiverOfWrongType)1198*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1199*d9f75844SAndroid Build Coastguard Worker        AddTrackDoesNotReuseTransceiverOfWrongType) {
1200*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1201*d9f75844SAndroid Build Coastguard Worker 
1202*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1203*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddVideoTrack("v");
1204*d9f75844SAndroid Build Coastguard Worker 
1205*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1206*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, transceivers.size());
1207*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender, transceivers[0]->sender());
1208*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender, transceivers[1]->sender());
1209*d9f75844SAndroid Build Coastguard Worker }
1210*d9f75844SAndroid Build Coastguard Worker 
1211*d9f75844SAndroid Build Coastguard Worker // Test that the first available transceiver is reused by AddTrack when multiple
1212*d9f75844SAndroid Build Coastguard Worker // are available.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackReusesFirstMatchingTransceiver)1213*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1214*d9f75844SAndroid Build Coastguard Worker        AddTrackReusesFirstMatchingTransceiver) {
1215*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1216*d9f75844SAndroid Build Coastguard Worker 
1217*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1218*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1219*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1220*d9f75844SAndroid Build Coastguard Worker 
1221*d9f75844SAndroid Build Coastguard Worker   auto transceivers = caller->pc()->GetTransceivers();
1222*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, transceivers.size());
1223*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender, transceivers[0]->sender());
1224*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender, transceivers[1]->sender());
1225*d9f75844SAndroid Build Coastguard Worker }
1226*d9f75844SAndroid Build Coastguard Worker 
1227*d9f75844SAndroid Build Coastguard Worker // Test that a call to AddTrack that reuses a transceiver will change the
1228*d9f75844SAndroid Build Coastguard Worker // direction from inactive to sendonly.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackChangesDirectionFromInactiveToSendOnly)1229*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1230*d9f75844SAndroid Build Coastguard Worker        AddTrackChangesDirectionFromInactiveToSendOnly) {
1231*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1232*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1233*d9f75844SAndroid Build Coastguard Worker 
1234*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1235*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kInactive;
1236*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1237*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1238*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1239*d9f75844SAndroid Build Coastguard Worker 
1240*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1241*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1242*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1243*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("a"));
1244*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1245*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1246*d9f75844SAndroid Build Coastguard Worker 
1247*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
1248*d9f75844SAndroid Build Coastguard Worker }
1249*d9f75844SAndroid Build Coastguard Worker 
1250*d9f75844SAndroid Build Coastguard Worker // Test that a call to AddTrack that reuses a transceiver will change the
1251*d9f75844SAndroid Build Coastguard Worker // direction from recvonly to sendrecv.
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackChangesDirectionFromRecvOnlyToSendRecv)1252*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1253*d9f75844SAndroid Build Coastguard Worker        AddTrackChangesDirectionFromRecvOnlyToSendRecv) {
1254*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1255*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1256*d9f75844SAndroid Build Coastguard Worker 
1257*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1258*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kRecvOnly;
1259*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1260*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1261*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1262*d9f75844SAndroid Build Coastguard Worker 
1263*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1264*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1265*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1266*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddAudioTrack("a"));
1267*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1268*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1269*d9f75844SAndroid Build Coastguard Worker 
1270*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
1271*d9f75844SAndroid Build Coastguard Worker }
1272*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackCreatesSenderWithTrackId)1273*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackCreatesSenderWithTrackId) {
1274*d9f75844SAndroid Build Coastguard Worker   const std::string kTrackId = "audio_track";
1275*d9f75844SAndroid Build Coastguard Worker 
1276*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1277*d9f75844SAndroid Build Coastguard Worker 
1278*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack(kTrackId);
1279*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddTrack(audio_track);
1280*d9f75844SAndroid Build Coastguard Worker 
1281*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kTrackId, sender->id());
1282*d9f75844SAndroid Build Coastguard Worker }
1283*d9f75844SAndroid Build Coastguard Worker 
1284*d9f75844SAndroid Build Coastguard Worker // Unified Plan AddTrack error handling.
1285*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackErrorIfClosed)1286*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfClosed) {
1287*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1288*d9f75844SAndroid Build Coastguard Worker 
1289*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("a");
1290*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
1291*d9f75844SAndroid Build Coastguard Worker 
1292*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1293*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1294*d9f75844SAndroid Build Coastguard Worker   auto result = caller->pc()->AddTrack(audio_track, std::vector<std::string>());
1295*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_STATE, result.error().type());
1296*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1297*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1298*d9f75844SAndroid Build Coastguard Worker }
1299*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddTrackErrorIfTrackAlreadyHasSender)1300*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddTrackErrorIfTrackAlreadyHasSender) {
1301*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1302*d9f75844SAndroid Build Coastguard Worker 
1303*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller->CreateAudioTrack("a");
1304*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->AddTrack(audio_track));
1305*d9f75844SAndroid Build Coastguard Worker 
1306*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1307*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1308*d9f75844SAndroid Build Coastguard Worker   auto result = caller->pc()->AddTrack(audio_track, std::vector<std::string>());
1309*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
1310*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1311*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1312*d9f75844SAndroid Build Coastguard Worker }
1313*d9f75844SAndroid Build Coastguard Worker 
1314*d9f75844SAndroid Build Coastguard Worker // Unified Plan RemoveTrack tests.
1315*d9f75844SAndroid Build Coastguard Worker 
1316*d9f75844SAndroid Build Coastguard Worker // Test that calling RemoveTrack on a sender with a previously-added track
1317*d9f75844SAndroid Build Coastguard Worker // clears the sender's track.
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackClearsSenderTrack)1318*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackClearsSenderTrack) {
1319*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1320*d9f75844SAndroid Build Coastguard Worker 
1321*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1322*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
1323*d9f75844SAndroid Build Coastguard Worker 
1324*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(sender->track());
1325*d9f75844SAndroid Build Coastguard Worker }
1326*d9f75844SAndroid Build Coastguard Worker 
1327*d9f75844SAndroid Build Coastguard Worker // Test that calling RemoveTrack on a sender where the transceiver is configured
1328*d9f75844SAndroid Build Coastguard Worker // in the sendrecv direction changes the transceiver's direction to recvonly.
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackChangesDirectionFromSendRecvToRecvOnly)1329*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1330*d9f75844SAndroid Build Coastguard Worker        RemoveTrackChangesDirectionFromSendRecvToRecvOnly) {
1331*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1332*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1333*d9f75844SAndroid Build Coastguard Worker 
1334*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1335*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kSendRecv;
1336*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1337*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
1338*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1339*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1340*d9f75844SAndroid Build Coastguard Worker 
1341*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1342*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1343*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1344*d9f75844SAndroid Build Coastguard Worker 
1345*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(transceiver->sender()).ok());
1346*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1347*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1348*d9f75844SAndroid Build Coastguard Worker 
1349*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceiver->direction());
1350*d9f75844SAndroid Build Coastguard Worker }
1351*d9f75844SAndroid Build Coastguard Worker 
1352*d9f75844SAndroid Build Coastguard Worker // Test that calling RemoveTrack on a sender where the transceiver is configured
1353*d9f75844SAndroid Build Coastguard Worker // in the sendonly direction changes the transceiver's direction to inactive.
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackChangesDirectionFromSendOnlyToInactive)1354*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1355*d9f75844SAndroid Build Coastguard Worker        RemoveTrackChangesDirectionFromSendOnlyToInactive) {
1356*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1357*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1358*d9f75844SAndroid Build Coastguard Worker 
1359*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1360*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kSendOnly;
1361*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1362*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
1363*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1364*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1365*d9f75844SAndroid Build Coastguard Worker 
1366*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1367*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1368*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1369*d9f75844SAndroid Build Coastguard Worker 
1370*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(transceiver->sender()).ok());
1371*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1372*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1373*d9f75844SAndroid Build Coastguard Worker 
1374*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver->direction());
1375*d9f75844SAndroid Build Coastguard Worker }
1376*d9f75844SAndroid Build Coastguard Worker 
1377*d9f75844SAndroid Build Coastguard Worker // Test that calling RemoveTrack with a sender that has a null track results in
1378*d9f75844SAndroid Build Coastguard Worker // no change in state.
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackWithNullSenderTrackIsNoOp)1379*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackWithNullSenderTrackIsNoOp) {
1380*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1381*d9f75844SAndroid Build Coastguard Worker 
1382*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1383*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->pc()->GetTransceivers()[0];
1384*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->SetTrack(nullptr));
1385*d9f75844SAndroid Build Coastguard Worker 
1386*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1387*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1388*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
1389*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1390*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1391*d9f75844SAndroid Build Coastguard Worker 
1392*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
1393*d9f75844SAndroid Build Coastguard Worker }
1394*d9f75844SAndroid Build Coastguard Worker 
1395*d9f75844SAndroid Build Coastguard Worker // Unified Plan RemoveTrack error handling.
1396*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackErrorIfClosed)1397*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, RemoveTrackErrorIfClosed) {
1398*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1399*d9f75844SAndroid Build Coastguard Worker 
1400*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1401*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
1402*d9f75844SAndroid Build Coastguard Worker 
1403*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1404*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1405*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->pc()->RemoveTrackOrError(sender).ok());
1406*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1407*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1408*d9f75844SAndroid Build Coastguard Worker }
1409*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,RemoveTrackNoErrorIfTrackAlreadyRemoved)1410*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1411*d9f75844SAndroid Build Coastguard Worker        RemoveTrackNoErrorIfTrackAlreadyRemoved) {
1412*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1413*d9f75844SAndroid Build Coastguard Worker 
1414*d9f75844SAndroid Build Coastguard Worker   auto sender = caller->AddAudioTrack("a");
1415*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
1416*d9f75844SAndroid Build Coastguard Worker 
1417*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1418*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1419*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->RemoveTrackOrError(sender).ok());
1420*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1421*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1422*d9f75844SAndroid Build Coastguard Worker }
1423*d9f75844SAndroid Build Coastguard Worker 
1424*d9f75844SAndroid Build Coastguard Worker // Test that setting offers that add/remove/add a track repeatedly without
1425*d9f75844SAndroid Build Coastguard Worker // setting the appropriate answer in between works.
1426*d9f75844SAndroid Build Coastguard Worker // These are regression tests for bugs.webrtc.org/9401
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddRemoveAddTrackOffersWorksAudio)1427*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddRemoveAddTrackOffersWorksAudio) {
1428*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1429*d9f75844SAndroid Build Coastguard Worker 
1430*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddAudioTrack("audio1");
1431*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1432*d9f75844SAndroid Build Coastguard Worker 
1433*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(sender1);
1434*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1435*d9f75844SAndroid Build Coastguard Worker 
1436*d9f75844SAndroid Build Coastguard Worker   // This will re-use the transceiver created by the first AddTrack.
1437*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddAudioTrack("audio2");
1438*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1439*d9f75844SAndroid Build Coastguard Worker 
1440*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, caller->pc()->GetTransceivers().size());
1441*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender1, sender2);
1442*d9f75844SAndroid Build Coastguard Worker }
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddRemoveAddTrackOffersWorksVideo)1443*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, AddRemoveAddTrackOffersWorksVideo) {
1444*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1445*d9f75844SAndroid Build Coastguard Worker 
1446*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddVideoTrack("video1");
1447*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1448*d9f75844SAndroid Build Coastguard Worker 
1449*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(sender1);
1450*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1451*d9f75844SAndroid Build Coastguard Worker 
1452*d9f75844SAndroid Build Coastguard Worker   // This will re-use the transceiver created by the first AddTrack.
1453*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddVideoTrack("video2");
1454*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1455*d9f75844SAndroid Build Coastguard Worker 
1456*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, caller->pc()->GetTransceivers().size());
1457*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender1, sender2);
1458*d9f75844SAndroid Build Coastguard Worker }
1459*d9f75844SAndroid Build Coastguard Worker 
1460*d9f75844SAndroid Build Coastguard Worker // Test that CreateOffer succeeds if two tracks with the same label are added.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CreateOfferSameTrackLabel)1461*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, CreateOfferSameTrackLabel) {
1462*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1463*d9f75844SAndroid Build Coastguard Worker 
1464*d9f75844SAndroid Build Coastguard Worker   auto audio_sender = caller->AddAudioTrack("track", {});
1465*d9f75844SAndroid Build Coastguard Worker   auto video_sender = caller->AddVideoTrack("track", {});
1466*d9f75844SAndroid Build Coastguard Worker 
1467*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->CreateOffer());
1468*d9f75844SAndroid Build Coastguard Worker 
1469*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_sender->track()->id(), video_sender->track()->id());
1470*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(audio_sender->id(), video_sender->id());
1471*d9f75844SAndroid Build Coastguard Worker }
1472*d9f75844SAndroid Build Coastguard Worker 
1473*d9f75844SAndroid Build Coastguard Worker // Test that CreateAnswer succeeds if two tracks with the same label are added.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CreateAnswerSameTrackLabel)1474*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, CreateAnswerSameTrackLabel) {
1475*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1476*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1477*d9f75844SAndroid Build Coastguard Worker 
1478*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit recvonly;
1479*d9f75844SAndroid Build Coastguard Worker   recvonly.direction = RtpTransceiverDirection::kRecvOnly;
1480*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, recvonly);
1481*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, recvonly);
1482*d9f75844SAndroid Build Coastguard Worker 
1483*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1484*d9f75844SAndroid Build Coastguard Worker 
1485*d9f75844SAndroid Build Coastguard Worker   auto audio_sender = callee->AddAudioTrack("track", {});
1486*d9f75844SAndroid Build Coastguard Worker   auto video_sender = callee->AddVideoTrack("track", {});
1487*d9f75844SAndroid Build Coastguard Worker 
1488*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->CreateAnswer());
1489*d9f75844SAndroid Build Coastguard Worker 
1490*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_sender->track()->id(), video_sender->track()->id());
1491*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(audio_sender->id(), video_sender->id());
1492*d9f75844SAndroid Build Coastguard Worker }
1493*d9f75844SAndroid Build Coastguard Worker 
1494*d9f75844SAndroid Build Coastguard Worker // Test that calling AddTrack, RemoveTrack and AddTrack again creates a second
1495*d9f75844SAndroid Build Coastguard Worker // m= section with a random sender id (different from the first, now rejected,
1496*d9f75844SAndroid Build Coastguard Worker // m= section).
TEST_F(PeerConnectionRtpTestUnifiedPlan,AddRemoveAddTrackGeneratesNewSenderId)1497*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1498*d9f75844SAndroid Build Coastguard Worker        AddRemoveAddTrackGeneratesNewSenderId) {
1499*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1500*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1501*d9f75844SAndroid Build Coastguard Worker 
1502*d9f75844SAndroid Build Coastguard Worker   auto track = caller->CreateVideoTrack("video");
1503*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddTrack(track);
1504*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1505*d9f75844SAndroid Build Coastguard Worker 
1506*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(sender1);
1507*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1508*d9f75844SAndroid Build Coastguard Worker 
1509*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddTrack(track);
1510*d9f75844SAndroid Build Coastguard Worker 
1511*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender1, sender2);
1512*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(sender1->id(), sender2->id());
1513*d9f75844SAndroid Build Coastguard Worker   std::string sender2_id = sender2->id();
1514*d9f75844SAndroid Build Coastguard Worker 
1515*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1516*d9f75844SAndroid Build Coastguard Worker 
1517*d9f75844SAndroid Build Coastguard Worker   // The sender's ID should not change after negotiation.
1518*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sender2_id, sender2->id());
1519*d9f75844SAndroid Build Coastguard Worker }
1520*d9f75844SAndroid Build Coastguard Worker 
1521*d9f75844SAndroid Build Coastguard Worker // Test that OnRenegotiationNeeded is fired if SetDirection is called on an
1522*d9f75844SAndroid Build Coastguard Worker // active RtpTransceiver with a new direction.
TEST_F(PeerConnectionRtpTestUnifiedPlan,RenegotiationNeededAfterTransceiverSetDirection)1523*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1524*d9f75844SAndroid Build Coastguard Worker        RenegotiationNeededAfterTransceiverSetDirection) {
1525*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1526*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1527*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1528*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1529*d9f75844SAndroid Build Coastguard Worker 
1530*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1531*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1532*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1533*d9f75844SAndroid Build Coastguard Worker 
1534*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1535*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1536*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1537*d9f75844SAndroid Build Coastguard Worker 
1538*d9f75844SAndroid Build Coastguard Worker   transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive);
1539*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1540*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1541*d9f75844SAndroid Build Coastguard Worker }
1542*d9f75844SAndroid Build Coastguard Worker 
1543*d9f75844SAndroid Build Coastguard Worker // Test that OnRenegotiationNeeded is not fired if SetDirection is called on an
1544*d9f75844SAndroid Build Coastguard Worker // active RtpTransceiver with current direction.
TEST_F(PeerConnectionRtpTestUnifiedPlan,NoRenegotiationNeededAfterTransceiverSetSameDirection)1545*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1546*d9f75844SAndroid Build Coastguard Worker        NoRenegotiationNeededAfterTransceiverSetSameDirection) {
1547*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1548*d9f75844SAndroid Build Coastguard Worker 
1549*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1550*d9f75844SAndroid Build Coastguard Worker 
1551*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1552*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1553*d9f75844SAndroid Build Coastguard Worker   transceiver->SetDirectionWithError(transceiver->direction());
1554*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1555*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1556*d9f75844SAndroid Build Coastguard Worker }
1557*d9f75844SAndroid Build Coastguard Worker 
1558*d9f75844SAndroid Build Coastguard Worker // Test that OnRenegotiationNeeded is not fired if SetDirection is called on a
1559*d9f75844SAndroid Build Coastguard Worker // stopped RtpTransceiver.
TEST_F(PeerConnectionRtpTestUnifiedPlan,NoRenegotiationNeededAfterSetDirectionOnStoppedTransceiver)1560*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1561*d9f75844SAndroid Build Coastguard Worker        NoRenegotiationNeededAfterSetDirectionOnStoppedTransceiver) {
1562*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1563*d9f75844SAndroid Build Coastguard Worker 
1564*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1565*d9f75844SAndroid Build Coastguard Worker   transceiver->StopInternal();
1566*d9f75844SAndroid Build Coastguard Worker 
1567*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1568*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1569*d9f75844SAndroid Build Coastguard Worker   transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive);
1570*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1571*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1572*d9f75844SAndroid Build Coastguard Worker }
1573*d9f75844SAndroid Build Coastguard Worker 
1574*d9f75844SAndroid Build Coastguard Worker // Test that currentDirection returnes "stopped" if the transceiver was stopped.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckStoppedCurrentDirectionOnStoppedTransceiver)1575*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1576*d9f75844SAndroid Build Coastguard Worker        CheckStoppedCurrentDirectionOnStoppedTransceiver) {
1577*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1578*d9f75844SAndroid Build Coastguard Worker 
1579*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1580*d9f75844SAndroid Build Coastguard Worker   transceiver->StopInternal();
1581*d9f75844SAndroid Build Coastguard Worker 
1582*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver->stopping());
1583*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver->stopped());
1584*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped,
1585*d9f75844SAndroid Build Coastguard Worker             transceiver->current_direction());
1586*d9f75844SAndroid Build Coastguard Worker }
1587*d9f75844SAndroid Build Coastguard Worker 
1588*d9f75844SAndroid Build Coastguard Worker // Test that InvalidState is thrown on a stopping transceiver.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckForInvalidStateOnStoppingTransceiver)1589*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1590*d9f75844SAndroid Build Coastguard Worker        CheckForInvalidStateOnStoppingTransceiver) {
1591*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1592*d9f75844SAndroid Build Coastguard Worker 
1593*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1594*d9f75844SAndroid Build Coastguard Worker   transceiver->StopStandard();
1595*d9f75844SAndroid Build Coastguard Worker 
1596*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver->stopping());
1597*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(transceiver->stopped());
1598*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1599*d9f75844SAndroid Build Coastguard Worker       RTCErrorType::INVALID_STATE,
1600*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
1601*d9f75844SAndroid Build Coastguard Worker           .type());
1602*d9f75844SAndroid Build Coastguard Worker }
1603*d9f75844SAndroid Build Coastguard Worker 
1604*d9f75844SAndroid Build Coastguard Worker // Test that InvalidState is thrown on a stopped transceiver.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckForInvalidStateOnStoppedTransceiver)1605*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1606*d9f75844SAndroid Build Coastguard Worker        CheckForInvalidStateOnStoppedTransceiver) {
1607*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1608*d9f75844SAndroid Build Coastguard Worker 
1609*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1610*d9f75844SAndroid Build Coastguard Worker   transceiver->StopInternal();
1611*d9f75844SAndroid Build Coastguard Worker 
1612*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver->stopping());
1613*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(transceiver->stopped());
1614*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1615*d9f75844SAndroid Build Coastguard Worker       RTCErrorType::INVALID_STATE,
1616*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kInactive)
1617*d9f75844SAndroid Build Coastguard Worker           .type());
1618*d9f75844SAndroid Build Coastguard Worker }
1619*d9f75844SAndroid Build Coastguard Worker 
1620*d9f75844SAndroid Build Coastguard Worker // Test that TypeError is thrown if the direction is set to "stopped".
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckForTypeErrorForStoppedOnTransceiver)1621*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1622*d9f75844SAndroid Build Coastguard Worker        CheckForTypeErrorForStoppedOnTransceiver) {
1623*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1624*d9f75844SAndroid Build Coastguard Worker 
1625*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1626*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
1627*d9f75844SAndroid Build Coastguard Worker       RTCErrorType::INVALID_PARAMETER,
1628*d9f75844SAndroid Build Coastguard Worker       transceiver->SetDirectionWithError(RtpTransceiverDirection::kStopped)
1629*d9f75844SAndroid Build Coastguard Worker           .type());
1630*d9f75844SAndroid Build Coastguard Worker }
1631*d9f75844SAndroid Build Coastguard Worker 
1632*d9f75844SAndroid Build Coastguard Worker // Test that you can do createOffer/setLocalDescription with a stopped
1633*d9f75844SAndroid Build Coastguard Worker // media section.
TEST_F(PeerConnectionRtpTestUnifiedPlan,SetLocalDescriptionWithStoppedMediaSection)1634*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1635*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionWithStoppedMediaSection) {
1636*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1637*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1638*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1639*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1640*d9f75844SAndroid Build Coastguard Worker   callee->pc()->GetTransceivers()[0]->StopStandard();
1641*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1642*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped,
1643*d9f75844SAndroid Build Coastguard Worker             transceiver->current_direction());
1644*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1645*d9f75844SAndroid Build Coastguard Worker }
1646*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,StopAndNegotiateCausesTransceiverToDisappear)1647*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1648*d9f75844SAndroid Build Coastguard Worker        StopAndNegotiateCausesTransceiverToDisappear) {
1649*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1650*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1651*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1652*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1653*d9f75844SAndroid Build Coastguard Worker   callee->pc()->GetTransceivers()[0]->StopStandard();
1654*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1655*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RtpTransceiverDirection::kStopped,
1656*d9f75844SAndroid Build Coastguard Worker             transceiver->current_direction());
1657*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller->pc()->GetTransceivers().size());
1658*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee->pc()->GetTransceivers().size());
1659*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller->pc()->GetSenders().size());
1660*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee->pc()->GetSenders().size());
1661*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller->pc()->GetReceivers().size());
1662*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee->pc()->GetReceivers().size());
1663*d9f75844SAndroid Build Coastguard Worker }
1664*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRtpTestUnifiedPlan,SetLocalDescriptionWorksAfterRepeatedAddRemove)1665*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1666*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionWorksAfterRepeatedAddRemove) {
1667*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1668*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1669*d9f75844SAndroid Build Coastguard Worker   auto video_track = caller->CreateVideoTrack("v");
1670*d9f75844SAndroid Build Coastguard Worker   auto track = caller->CreateAudioTrack("a");
1671*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(video_track);
1672*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(track);
1673*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1674*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(transceiver->sender());
1675*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1676*d9f75844SAndroid Build Coastguard Worker   caller->AddTrack(track);
1677*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1678*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(transceiver->sender());
1679*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1680*d9f75844SAndroid Build Coastguard Worker }
1681*d9f75844SAndroid Build Coastguard Worker 
1682*d9f75844SAndroid Build Coastguard Worker // This is a repro of Chromium bug https://crbug.com/1134686
TEST_F(PeerConnectionRtpTestUnifiedPlan,SetLocalDescriptionWorksAfterRepeatedAddRemoveWithRemoteReject)1683*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1684*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionWorksAfterRepeatedAddRemoveWithRemoteReject) {
1685*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1686*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1687*d9f75844SAndroid Build Coastguard Worker   auto video_track = caller->CreateVideoTrack("v");
1688*d9f75844SAndroid Build Coastguard Worker   auto track = caller->CreateAudioTrack("a");
1689*d9f75844SAndroid Build Coastguard Worker   caller->AddTransceiver(video_track);
1690*d9f75844SAndroid Build Coastguard Worker   auto transceiver = caller->AddTransceiver(track);
1691*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1692*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(transceiver->sender());
1693*d9f75844SAndroid Build Coastguard Worker   ExchangeOfferAnswerWhereRemoteStopsTransceiver(caller.get(), callee.get(), 1);
1694*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1695*d9f75844SAndroid Build Coastguard Worker   caller->AddTrack(track);
1696*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1697*d9f75844SAndroid Build Coastguard Worker   caller->pc()->RemoveTrackOrError(transceiver->sender());
1698*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1699*d9f75844SAndroid Build Coastguard Worker }
1700*d9f75844SAndroid Build Coastguard Worker 
1701*d9f75844SAndroid Build Coastguard Worker // Test that AddTransceiver fails if trying to use unimplemented RTP encoding
1702*d9f75844SAndroid Build Coastguard Worker // parameters with the send_encodings parameters.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckForUnsupportedEncodingParameters)1703*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1704*d9f75844SAndroid Build Coastguard Worker        CheckForUnsupportedEncodingParameters) {
1705*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1706*d9f75844SAndroid Build Coastguard Worker 
1707*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1708*d9f75844SAndroid Build Coastguard Worker   init.send_encodings.emplace_back();
1709*d9f75844SAndroid Build Coastguard Worker 
1710*d9f75844SAndroid Build Coastguard Worker   auto default_send_encodings = init.send_encodings;
1711*d9f75844SAndroid Build Coastguard Worker 
1712*d9f75844SAndroid Build Coastguard Worker   // Unimplemented RtpParameters: ssrc, codec_payload_type, fec, rtx, dtx,
1713*d9f75844SAndroid Build Coastguard Worker   // ptime, scale_framerate_down_by, dependency_rids.
1714*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].ssrc = 1;
1715*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
1716*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1717*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init)
1718*d9f75844SAndroid Build Coastguard Worker                 .error()
1719*d9f75844SAndroid Build Coastguard Worker                 .type());
1720*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1721*d9f75844SAndroid Build Coastguard Worker }
1722*d9f75844SAndroid Build Coastguard Worker 
1723*d9f75844SAndroid Build Coastguard Worker // Test that AddTransceiver fails if trying to use invalid RTP encoding
1724*d9f75844SAndroid Build Coastguard Worker // parameters with the send_encodings parameters.
TEST_F(PeerConnectionRtpTestUnifiedPlan,CheckForInvalidEncodingParameters)1725*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, CheckForInvalidEncodingParameters) {
1726*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1727*d9f75844SAndroid Build Coastguard Worker 
1728*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1729*d9f75844SAndroid Build Coastguard Worker   init.send_encodings.emplace_back();
1730*d9f75844SAndroid Build Coastguard Worker 
1731*d9f75844SAndroid Build Coastguard Worker   auto default_send_encodings = init.send_encodings;
1732*d9f75844SAndroid Build Coastguard Worker 
1733*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].scale_resolution_down_by = 0.5;
1734*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1735*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1736*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1737*d9f75844SAndroid Build Coastguard Worker                 .error()
1738*d9f75844SAndroid Build Coastguard Worker                 .type());
1739*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1740*d9f75844SAndroid Build Coastguard Worker 
1741*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].bitrate_priority = 0;
1742*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1743*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1744*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1745*d9f75844SAndroid Build Coastguard Worker                 .error()
1746*d9f75844SAndroid Build Coastguard Worker                 .type());
1747*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1748*d9f75844SAndroid Build Coastguard Worker 
1749*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].min_bitrate_bps = 200000;
1750*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].max_bitrate_bps = 100000;
1751*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1752*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1753*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1754*d9f75844SAndroid Build Coastguard Worker                 .error()
1755*d9f75844SAndroid Build Coastguard Worker                 .type());
1756*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1757*d9f75844SAndroid Build Coastguard Worker 
1758*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].num_temporal_layers = 0;
1759*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1760*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1761*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1762*d9f75844SAndroid Build Coastguard Worker                 .error()
1763*d9f75844SAndroid Build Coastguard Worker                 .type());
1764*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1765*d9f75844SAndroid Build Coastguard Worker 
1766*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].num_temporal_layers = 5;
1767*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCErrorType::INVALID_RANGE,
1768*d9f75844SAndroid Build Coastguard Worker             caller->pc()
1769*d9f75844SAndroid Build Coastguard Worker                 ->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init)
1770*d9f75844SAndroid Build Coastguard Worker                 .error()
1771*d9f75844SAndroid Build Coastguard Worker                 .type());
1772*d9f75844SAndroid Build Coastguard Worker   init.send_encodings = default_send_encodings;
1773*d9f75844SAndroid Build Coastguard Worker }
1774*d9f75844SAndroid Build Coastguard Worker 
1775*d9f75844SAndroid Build Coastguard Worker // Test that AddTransceiver transfers the send_encodings to the sender and they
1776*d9f75844SAndroid Build Coastguard Worker // are retained after SetLocalDescription().
TEST_F(PeerConnectionRtpTestUnifiedPlan,SendEncodingsPassedToSender)1777*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan, SendEncodingsPassedToSender) {
1778*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1779*d9f75844SAndroid Build Coastguard Worker 
1780*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1781*d9f75844SAndroid Build Coastguard Worker   init.send_encodings.emplace_back();
1782*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].active = false;
1783*d9f75844SAndroid Build Coastguard Worker   init.send_encodings[0].max_bitrate_bps = 180000;
1784*d9f75844SAndroid Build Coastguard Worker 
1785*d9f75844SAndroid Build Coastguard Worker   auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
1786*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(result.ok());
1787*d9f75844SAndroid Build Coastguard Worker 
1788*d9f75844SAndroid Build Coastguard Worker   auto init_send_encodings = result.value()->sender()->init_send_encodings();
1789*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(init_send_encodings[0].active);
1790*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(init_send_encodings[0].max_bitrate_bps, 180000);
1791*d9f75844SAndroid Build Coastguard Worker 
1792*d9f75844SAndroid Build Coastguard Worker   auto parameters = result.value()->sender()->GetParameters();
1793*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(parameters.encodings[0].active);
1794*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(parameters.encodings[0].max_bitrate_bps, 180000);
1795*d9f75844SAndroid Build Coastguard Worker 
1796*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
1797*d9f75844SAndroid Build Coastguard Worker 
1798*d9f75844SAndroid Build Coastguard Worker   parameters = result.value()->sender()->GetParameters();
1799*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(parameters.encodings[0].active);
1800*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(parameters.encodings[0].max_bitrate_bps, 180000);
1801*d9f75844SAndroid Build Coastguard Worker }
1802*d9f75844SAndroid Build Coastguard Worker 
1803*d9f75844SAndroid Build Coastguard Worker // Test MSID signaling between Unified Plan and Plan B endpoints. There are two
1804*d9f75844SAndroid Build Coastguard Worker // options for this kind of signaling: media section based (a=msid) and ssrc
1805*d9f75844SAndroid Build Coastguard Worker // based (a=ssrc MSID). While JSEP only specifies media section MSID signaling,
1806*d9f75844SAndroid Build Coastguard Worker // we want to ensure compatibility with older Plan B endpoints that might expect
1807*d9f75844SAndroid Build Coastguard Worker // ssrc based MSID signaling. Thus we test here that Unified Plan offers both
1808*d9f75844SAndroid Build Coastguard Worker // types but answers with the same type as the offer.
1809*d9f75844SAndroid Build Coastguard Worker 
1810*d9f75844SAndroid Build Coastguard Worker class PeerConnectionMsidSignalingTest
1811*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionRtpTestUnifiedPlan {};
1812*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionMsidSignalingTest,UnifiedPlanTalkingToOurself)1813*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanTalkingToOurself) {
1814*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithUnifiedPlan();
1815*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("caller_audio");
1816*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithUnifiedPlan();
1817*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("callee_audio");
1818*d9f75844SAndroid Build Coastguard Worker 
1819*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1820*d9f75844SAndroid Build Coastguard Worker 
1821*d9f75844SAndroid Build Coastguard Worker   // Offer should have had both a=msid and a=ssrc MSID lines.
1822*d9f75844SAndroid Build Coastguard Worker   auto* offer = callee->pc()->remote_description();
1823*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1824*d9f75844SAndroid Build Coastguard Worker              cricket::kMsidSignalingSsrcAttribute),
1825*d9f75844SAndroid Build Coastguard Worker             offer->description()->msid_signaling());
1826*d9f75844SAndroid Build Coastguard Worker 
1827*d9f75844SAndroid Build Coastguard Worker   // Answer should have had only a=msid lines.
1828*d9f75844SAndroid Build Coastguard Worker   auto* answer = caller->pc()->remote_description();
1829*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1830*d9f75844SAndroid Build Coastguard Worker             answer->description()->msid_signaling());
1831*d9f75844SAndroid Build Coastguard Worker }
1832*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionMsidSignalingTest,PlanBOfferToUnifiedPlanAnswer)1833*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionMsidSignalingTest, PlanBOfferToUnifiedPlanAnswer) {
1834*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithPlanB();
1835*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("caller_audio");
1836*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithUnifiedPlan();
1837*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("callee_audio");
1838*d9f75844SAndroid Build Coastguard Worker 
1839*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1840*d9f75844SAndroid Build Coastguard Worker 
1841*d9f75844SAndroid Build Coastguard Worker   // Offer should have only a=ssrc MSID lines.
1842*d9f75844SAndroid Build Coastguard Worker   auto* offer = callee->pc()->remote_description();
1843*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1844*d9f75844SAndroid Build Coastguard Worker             offer->description()->msid_signaling());
1845*d9f75844SAndroid Build Coastguard Worker 
1846*d9f75844SAndroid Build Coastguard Worker   // Answer should have only a=ssrc MSID lines to match the offer.
1847*d9f75844SAndroid Build Coastguard Worker   auto* answer = caller->pc()->remote_description();
1848*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1849*d9f75844SAndroid Build Coastguard Worker             answer->description()->msid_signaling());
1850*d9f75844SAndroid Build Coastguard Worker }
1851*d9f75844SAndroid Build Coastguard Worker 
1852*d9f75844SAndroid Build Coastguard Worker // This tests that a Plan B endpoint appropriately sets the remote description
1853*d9f75844SAndroid Build Coastguard Worker // from a Unified Plan offer. When the Unified Plan offer contains a=msid lines
1854*d9f75844SAndroid Build Coastguard Worker // that signal no stream ids or multiple stream ids we expect that the Plan B
1855*d9f75844SAndroid Build Coastguard Worker // endpoint always has exactly one media stream per track.
TEST_F(PeerConnectionMsidSignalingTest,UnifiedPlanToPlanBAnswer)1856*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanToPlanBAnswer) {
1857*d9f75844SAndroid Build Coastguard Worker   const std::string kStreamId1 = "audio_stream_1";
1858*d9f75844SAndroid Build Coastguard Worker   const std::string kStreamId2 = "audio_stream_2";
1859*d9f75844SAndroid Build Coastguard Worker 
1860*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithUnifiedPlan();
1861*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("caller_audio", {kStreamId1, kStreamId2});
1862*d9f75844SAndroid Build Coastguard Worker   caller->AddVideoTrack("caller_video", {});
1863*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithPlanB();
1864*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("callee_audio");
1865*d9f75844SAndroid Build Coastguard Worker   caller->AddVideoTrack("callee_video");
1866*d9f75844SAndroid Build Coastguard Worker 
1867*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1868*d9f75844SAndroid Build Coastguard Worker 
1869*d9f75844SAndroid Build Coastguard Worker   // Offer should have had both a=msid and a=ssrc MSID lines.
1870*d9f75844SAndroid Build Coastguard Worker   auto* offer = callee->pc()->remote_description();
1871*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1872*d9f75844SAndroid Build Coastguard Worker              cricket::kMsidSignalingSsrcAttribute),
1873*d9f75844SAndroid Build Coastguard Worker             offer->description()->msid_signaling());
1874*d9f75844SAndroid Build Coastguard Worker 
1875*d9f75844SAndroid Build Coastguard Worker   // Callee should always have 1 stream for all of it's receivers.
1876*d9f75844SAndroid Build Coastguard Worker   const auto& track_events = callee->observer()->add_track_events_;
1877*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, track_events.size());
1878*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, track_events[0].streams.size());
1879*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kStreamId1, track_events[0].streams[0]->id());
1880*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, track_events[1].streams.size());
1881*d9f75844SAndroid Build Coastguard Worker   // This autogenerated a stream id for the empty one signalled.
1882*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(track_events[1].streams[0]->id().empty());
1883*d9f75844SAndroid Build Coastguard Worker }
1884*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionMsidSignalingTest,PureUnifiedPlanToUs)1885*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionMsidSignalingTest, PureUnifiedPlanToUs) {
1886*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithUnifiedPlan();
1887*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("caller_audio");
1888*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithUnifiedPlan();
1889*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("callee_audio");
1890*d9f75844SAndroid Build Coastguard Worker 
1891*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
1892*d9f75844SAndroid Build Coastguard Worker   // Simulate a pure Unified Plan offerer by setting the MSID signaling to media
1893*d9f75844SAndroid Build Coastguard Worker   // section only.
1894*d9f75844SAndroid Build Coastguard Worker   offer->description()->set_msid_signaling(cricket::kMsidSignalingMediaSection);
1895*d9f75844SAndroid Build Coastguard Worker 
1896*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
1897*d9f75844SAndroid Build Coastguard Worker       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1898*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1899*d9f75844SAndroid Build Coastguard Worker 
1900*d9f75844SAndroid Build Coastguard Worker   // Answer should have only a=msid to match the offer.
1901*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
1902*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1903*d9f75844SAndroid Build Coastguard Worker             answer->description()->msid_signaling());
1904*d9f75844SAndroid Build Coastguard Worker }
1905*d9f75844SAndroid Build Coastguard Worker 
1906*d9f75844SAndroid Build Coastguard Worker // Sender setups in a call.
1907*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionRtpTest,CreateTwoSendersWithSameTrack)1908*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionRtpTest, CreateTwoSendersWithSameTrack) {
1909*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1910*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1911*d9f75844SAndroid Build Coastguard Worker 
1912*d9f75844SAndroid Build Coastguard Worker   auto track = caller->CreateAudioTrack("audio_track");
1913*d9f75844SAndroid Build Coastguard Worker   auto sender1 = caller->AddTrack(track);
1914*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(sender1);
1915*d9f75844SAndroid Build Coastguard Worker   // We need to temporarily reset the track for the subsequent AddTrack() to
1916*d9f75844SAndroid Build Coastguard Worker   // succeed.
1917*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(sender1->SetTrack(nullptr));
1918*d9f75844SAndroid Build Coastguard Worker   auto sender2 = caller->AddTrack(track);
1919*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(sender2);
1920*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(sender1->SetTrack(track.get()));
1921*d9f75844SAndroid Build Coastguard Worker 
1922*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
1923*d9f75844SAndroid Build Coastguard Worker     // TODO(hbos): When https://crbug.com/webrtc/8734 is resolved, this should
1924*d9f75844SAndroid Build Coastguard Worker     // return true, and doing `callee->SetRemoteDescription()` should work.
1925*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(caller->CreateOfferAndSetAsLocal());
1926*d9f75844SAndroid Build Coastguard Worker   } else {
1927*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(caller->CreateOfferAndSetAsLocal());
1928*d9f75844SAndroid Build Coastguard Worker   }
1929*d9f75844SAndroid Build Coastguard Worker }
1930*d9f75844SAndroid Build Coastguard Worker 
1931*d9f75844SAndroid Build Coastguard Worker // This test exercises the code path that fires a NegotiationNeeded
1932*d9f75844SAndroid Build Coastguard Worker // notification when the stream IDs of the local description differ from
1933*d9f75844SAndroid Build Coastguard Worker // the ones in the transceiver.
TEST_F(PeerConnectionRtpTestUnifiedPlan,ChangeAssociatedStreamsTriggersRenegotiation)1934*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRtpTestUnifiedPlan,
1935*d9f75844SAndroid Build Coastguard Worker        ChangeAssociatedStreamsTriggersRenegotiation) {
1936*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1937*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1938*d9f75844SAndroid Build Coastguard Worker 
1939*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit init;
1940*d9f75844SAndroid Build Coastguard Worker   init.direction = RtpTransceiverDirection::kSendRecv;
1941*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1942*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
1943*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1944*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1945*d9f75844SAndroid Build Coastguard Worker 
1946*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1947*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_legacy_renegotiation_needed();
1948*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1949*d9f75844SAndroid Build Coastguard Worker 
1950*d9f75844SAndroid Build Coastguard Worker   transceiver->sender()->SetStreams({"stream3", "stream4", "stream5"});
1951*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1952*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1953*d9f75844SAndroid Build Coastguard Worker 
1954*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1955*d9f75844SAndroid Build Coastguard Worker   auto callee_streams = callee->pc()->GetReceivers()[0]->streams();
1956*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(3u, callee_streams.size());
1957*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("stream3", callee_streams[0]->id());
1958*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("stream4", callee_streams[1]->id());
1959*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("stream5", callee_streams[2]->id());
1960*d9f75844SAndroid Build Coastguard Worker }
1961*d9f75844SAndroid Build Coastguard Worker 
1962*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PeerConnectionRtpTest,
1963*d9f75844SAndroid Build Coastguard Worker                          PeerConnectionRtpTest,
1964*d9f75844SAndroid Build Coastguard Worker                          Values(SdpSemantics::kPlanB_DEPRECATED,
1965*d9f75844SAndroid Build Coastguard Worker                                 SdpSemantics::kUnifiedPlan));
1966*d9f75844SAndroid Build Coastguard Worker 
1967*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
1968