blob: 942bd4652b9ac97019e59b3cabc71d8dd628b284 [file] [log] [blame]
Henrik Boström933d8b02017-10-10 10:05:16 -07001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <memory>
12#include <vector>
13
Karl Wiberg1b0eae32017-10-17 14:48:54 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070016#include "api/jsep.h"
17#include "api/mediastreaminterface.h"
18#include "api/peerconnectioninterface.h"
Steve Anton8e20f172018-03-06 10:55:04 -080019#include "api/umametrics.h"
Seth Hampson5b4f0752018-04-02 16:31:36 -070020#include "pc/mediasession.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070021#include "pc/mediastream.h"
22#include "pc/mediastreamtrack.h"
23#include "pc/peerconnectionwrapper.h"
Steve Antone831b8c2018-02-01 12:22:16 -080024#include "pc/sdputils.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070025#include "pc/test/fakeaudiocapturemodule.h"
26#include "pc/test/mockpeerconnectionobservers.h"
27#include "rtc_base/checks.h"
28#include "rtc_base/gunit.h"
29#include "rtc_base/ptr_util.h"
30#include "rtc_base/refcountedobject.h"
31#include "rtc_base/scoped_ref_ptr.h"
32#include "rtc_base/thread.h"
Steve Anton9158ef62017-11-27 13:01:52 -080033#include "test/gmock.h"
Henrik Boström933d8b02017-10-10 10:05:16 -070034
35// This file contains tests for RTP Media API-related behavior of
36// |webrtc::PeerConnection|, see https://w3c.github.io/webrtc-pc/#rtp-media-api.
37
Steve Anton9158ef62017-11-27 13:01:52 -080038namespace webrtc {
39
40using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
41using ::testing::ElementsAre;
42using ::testing::UnorderedElementsAre;
Henrik Boström933d8b02017-10-10 10:05:16 -070043
Henrik Boström31638672017-11-23 17:48:32 +010044const uint32_t kDefaultTimeout = 10000u;
45
46template <typename MethodFunctor>
47class OnSuccessObserver : public rtc::RefCountedObject<
48 webrtc::SetRemoteDescriptionObserverInterface> {
49 public:
50 explicit OnSuccessObserver(MethodFunctor on_success)
51 : on_success_(std::move(on_success)) {}
52
53 // webrtc::SetRemoteDescriptionObserverInterface implementation.
54 void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
55 RTC_CHECK(error.ok());
56 on_success_();
57 }
58
59 private:
60 MethodFunctor on_success_;
61};
62
Henrik Boström933d8b02017-10-10 10:05:16 -070063class PeerConnectionRtpTest : public testing::Test {
64 public:
65 PeerConnectionRtpTest()
Steve Anton9158ef62017-11-27 13:01:52 -080066 : pc_factory_(
67 CreatePeerConnectionFactory(rtc::Thread::Current(),
68 rtc::Thread::Current(),
69 rtc::Thread::Current(),
70 FakeAudioCaptureModule::Create(),
71 CreateBuiltinAudioEncoderFactory(),
72 CreateBuiltinAudioDecoderFactory(),
73 nullptr,
74 nullptr)) {}
Henrik Boström933d8b02017-10-10 10:05:16 -070075
Steve Anton9158ef62017-11-27 13:01:52 -080076 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection() {
77 return CreatePeerConnection(RTCConfiguration());
78 }
79
Steve Antone831b8c2018-02-01 12:22:16 -080080 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithPlanB() {
81 RTCConfiguration config;
82 config.sdp_semantics = SdpSemantics::kPlanB;
83 return CreatePeerConnection(config);
84 }
85
Steve Anton9158ef62017-11-27 13:01:52 -080086 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWithUnifiedPlan() {
87 RTCConfiguration config;
88 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
89 return CreatePeerConnection(config);
90 }
91
92 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
93 const RTCConfiguration& config) {
94 auto observer = rtc::MakeUnique<MockPeerConnectionObserver>();
Henrik Boström933d8b02017-10-10 10:05:16 -070095 auto pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr,
96 observer.get());
Steve Anton9158ef62017-11-27 13:01:52 -080097 return rtc::MakeUnique<PeerConnectionWrapper>(pc_factory_, pc,
98 std::move(observer));
Henrik Boström933d8b02017-10-10 10:05:16 -070099 }
100
101 protected:
Steve Anton9158ef62017-11-27 13:01:52 -0800102 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Henrik Boström933d8b02017-10-10 10:05:16 -0700103};
104
Henrik Boström31638672017-11-23 17:48:32 +0100105// These tests cover |webrtc::PeerConnectionObserver| callbacks firing upon
106// setting the remote description.
107class PeerConnectionRtpCallbacksTest : public PeerConnectionRtpTest {};
108
109TEST_F(PeerConnectionRtpCallbacksTest, AddTrackWithoutStreamFiresOnAddTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700110 auto caller = CreatePeerConnection();
111 auto callee = CreatePeerConnection();
112
Steve Anton2d6c76a2018-01-05 17:10:52 -0800113 ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track")));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700114 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700115
Henrik Boström31638672017-11-23 17:48:32 +0100116 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Seth Hampson5b4f0752018-04-02 16:31:36 -0700117 // Since we are not supporting the no stream case with Plan B, there should be
118 // a generated stream, even though we didn't set one with AddTrack.
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100119 auto& add_track_event = callee->observer()->add_track_events_[0];
Henrik Boström31638672017-11-23 17:48:32 +0100120 ASSERT_EQ(add_track_event.streams.size(), 1u);
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100121 EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
122 EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
Henrik Boström933d8b02017-10-10 10:05:16 -0700123}
124
Henrik Boström31638672017-11-23 17:48:32 +0100125TEST_F(PeerConnectionRtpCallbacksTest, AddTrackWithStreamFiresOnAddTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700126 auto caller = CreatePeerConnection();
127 auto callee = CreatePeerConnection();
128
Steve Anton2d6c76a2018-01-05 17:10:52 -0800129 ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"),
130 {"audio_stream"}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700131 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700132
Henrik Boström31638672017-11-23 17:48:32 +0100133 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100134 auto& add_track_event = callee->observer()->add_track_events_[0];
Henrik Boström31638672017-11-23 17:48:32 +0100135 ASSERT_EQ(add_track_event.streams.size(), 1u);
Seth Hampson13b8bad2018-03-13 16:05:28 -0700136 EXPECT_EQ("audio_stream", add_track_event.streams[0]->id());
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100137 EXPECT_TRUE(add_track_event.streams[0]->FindAudioTrack("audio_track"));
138 EXPECT_EQ(add_track_event.streams, add_track_event.receiver->streams());
Henrik Boström933d8b02017-10-10 10:05:16 -0700139}
140
Henrik Boström31638672017-11-23 17:48:32 +0100141TEST_F(PeerConnectionRtpCallbacksTest,
142 RemoveTrackWithoutStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700143 auto caller = CreatePeerConnection();
144 auto callee = CreatePeerConnection();
145
Steve Anton2d6c76a2018-01-05 17:10:52 -0800146 auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700147 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100148 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700149 EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700150 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700151
Henrik Boström31638672017-11-23 17:48:32 +0100152 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700153 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
154 callee->observer()->remove_track_events_);
155}
156
Henrik Boström31638672017-11-23 17:48:32 +0100157TEST_F(PeerConnectionRtpCallbacksTest,
158 RemoveTrackWithStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700159 auto caller = CreatePeerConnection();
160 auto callee = CreatePeerConnection();
161
Steve Anton2d6c76a2018-01-05 17:10:52 -0800162 auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"),
163 {"audio_stream"});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700164 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100165 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700166 EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700167 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700168
Henrik Boström31638672017-11-23 17:48:32 +0100169 ASSERT_EQ(callee->observer()->add_track_events_.size(), 1u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700170 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
171 callee->observer()->remove_track_events_);
172}
173
Henrik Boström31638672017-11-23 17:48:32 +0100174TEST_F(PeerConnectionRtpCallbacksTest,
175 RemoveTrackWithSharedStreamFiresOnRemoveTrack) {
Henrik Boström933d8b02017-10-10 10:05:16 -0700176 auto caller = CreatePeerConnection();
177 auto callee = CreatePeerConnection();
178
Seth Hampson845e8782018-03-02 11:34:10 -0800179 const char kSharedStreamId[] = "shared_audio_stream";
Steve Anton2d6c76a2018-01-05 17:10:52 -0800180 auto sender1 = caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
Seth Hampson845e8782018-03-02 11:34:10 -0800181 {kSharedStreamId});
Steve Anton2d6c76a2018-01-05 17:10:52 -0800182 auto sender2 = caller->AddTrack(caller->CreateAudioTrack("audio_track2"),
Seth Hampson845e8782018-03-02 11:34:10 -0800183 {kSharedStreamId});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700184 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström933d8b02017-10-10 10:05:16 -0700185
Henrik Boström31638672017-11-23 17:48:32 +0100186 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700187
188 // Remove "audio_track1".
189 EXPECT_TRUE(caller->pc()->RemoveTrack(sender1));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700190 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100191 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700192 EXPECT_EQ(
Steve Anton9158ef62017-11-27 13:01:52 -0800193 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
Henrik Boström933d8b02017-10-10 10:05:16 -0700194 callee->observer()->add_track_events_[0].receiver},
195 callee->observer()->remove_track_events_);
196
197 // Remove "audio_track2".
198 EXPECT_TRUE(caller->pc()->RemoveTrack(sender2));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700199 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100200 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
Henrik Boström933d8b02017-10-10 10:05:16 -0700201 EXPECT_EQ(callee->observer()->GetAddTrackReceivers(),
202 callee->observer()->remove_track_events_);
203}
204
Seth Hampson5b4f0752018-04-02 16:31:36 -0700205// Tests the edge case that if a stream ID changes for a given track that both
206// OnRemoveTrack and OnAddTrack is fired.
207TEST_F(PeerConnectionRtpCallbacksTest,
208 RemoteStreamIdChangesFiresOnRemoveAndOnAddTrack) {
209 auto caller = CreatePeerConnection();
210 auto callee = CreatePeerConnection();
211
212 const char kStreamId1[] = "stream1";
213 const char kStreamId2[] = "stream2";
214 caller->AddTrack(caller->CreateAudioTrack("audio_track1"), {kStreamId1});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700215 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700216 EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
217
218 // Change the stream ID of the sender in the session description.
219 auto offer = caller->CreateOfferAndSetAsLocal();
220 auto audio_desc = offer->description()->GetContentDescriptionByName("audio");
221 ASSERT_EQ(audio_desc->mutable_streams().size(), 1u);
222 audio_desc->mutable_streams()[0].set_stream_ids({kStreamId2});
223 ASSERT_TRUE(
Seth Hampson5897a6e2018-04-03 11:16:33 -0700224 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700225
226 ASSERT_EQ(callee->observer()->add_track_events_.size(), 2u);
227 EXPECT_EQ(callee->observer()->add_track_events_[1].streams[0]->id(),
228 kStreamId2);
229 ASSERT_EQ(callee->observer()->remove_track_events_.size(), 1u);
230 EXPECT_EQ(callee->observer()->remove_track_events_[0]->streams()[0]->id(),
231 kStreamId1);
232}
233
Steve Anton8b815cd2018-02-16 16:14:42 -0800234// Tests that setting a remote description with sending transceivers will fire
235// the OnTrack callback for each transceiver and setting a remote description
Seth Hampson5b4f0752018-04-02 16:31:36 -0700236// with receive only transceivers will not call OnTrack. One transceiver is
237// created without any stream_ids, while the other is created with multiple
238// stream_ids.
Steve Anton8b815cd2018-02-16 16:14:42 -0800239TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanAddTransceiverCallsOnTrack) {
Seth Hampson5b4f0752018-04-02 16:31:36 -0700240 const std::string kStreamId1 = "video_stream1";
241 const std::string kStreamId2 = "video_stream2";
Steve Anton8b815cd2018-02-16 16:14:42 -0800242 auto caller = CreatePeerConnectionWithUnifiedPlan();
243 auto callee = CreatePeerConnectionWithUnifiedPlan();
244
245 auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Seth Hampson5b4f0752018-04-02 16:31:36 -0700246 RtpTransceiverInit video_transceiver_init;
247 video_transceiver_init.stream_ids = {kStreamId1, kStreamId2};
248 auto video_transceiver =
249 caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, video_transceiver_init);
Steve Anton8b815cd2018-02-16 16:14:42 -0800250
251 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
252
253 ASSERT_EQ(0u, caller->observer()->on_track_transceivers_.size());
254 ASSERT_EQ(2u, callee->observer()->on_track_transceivers_.size());
255 EXPECT_EQ(audio_transceiver->mid(),
256 callee->pc()->GetTransceivers()[0]->mid());
257 EXPECT_EQ(video_transceiver->mid(),
258 callee->pc()->GetTransceivers()[1]->mid());
Seth Hampson5b4f0752018-04-02 16:31:36 -0700259 std::vector<rtc::scoped_refptr<MediaStreamInterface>> audio_streams =
260 callee->pc()->GetTransceivers()[0]->receiver()->streams();
261 std::vector<rtc::scoped_refptr<MediaStreamInterface>> video_streams =
262 callee->pc()->GetTransceivers()[1]->receiver()->streams();
263 ASSERT_EQ(0u, audio_streams.size());
264 ASSERT_EQ(2u, video_streams.size());
265 EXPECT_EQ(kStreamId1, video_streams[0]->id());
266 EXPECT_EQ(kStreamId2, video_streams[1]->id());
Steve Anton8b815cd2018-02-16 16:14:42 -0800267}
268
269// Test that doing additional offer/answer exchanges with no changes to tracks
270// will cause no additional OnTrack calls after the tracks have been negotiated.
271TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanReofferDoesNotCallOnTrack) {
272 auto caller = CreatePeerConnectionWithUnifiedPlan();
273 auto callee = CreatePeerConnectionWithUnifiedPlan();
274
275 caller->AddAudioTrack("audio");
276 callee->AddAudioTrack("audio");
277
278 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
279 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
280 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
281
282 // If caller reoffers with no changes expect no additional OnTrack calls.
283 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
284 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
285 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
286
287 // Also if callee reoffers with no changes expect no additional OnTrack calls.
288 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
289 EXPECT_EQ(1u, caller->observer()->on_track_transceivers_.size());
290 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
291}
292
293// Test that OnTrack is called when the transceiver direction changes to send
294// the track.
295TEST_F(PeerConnectionRtpCallbacksTest, UnifiedPlanSetDirectionCallsOnTrack) {
296 auto caller = CreatePeerConnectionWithUnifiedPlan();
297 auto callee = CreatePeerConnectionWithUnifiedPlan();
298
299 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
300 transceiver->SetDirection(RtpTransceiverDirection::kInactive);
301 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
302 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
303 EXPECT_EQ(0u, callee->observer()->on_track_transceivers_.size());
304
305 transceiver->SetDirection(RtpTransceiverDirection::kSendOnly);
306 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
307 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
308 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
309
310 // If the direction changes but it is still receiving on the remote side, then
311 // OnTrack should not be fired again.
312 transceiver->SetDirection(RtpTransceiverDirection::kSendRecv);
313 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
314 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
315 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
316}
317
318// Test that OnTrack is called twice when a sendrecv call is started, the callee
319// changes the direction to inactive, then changes it back to sendrecv.
320TEST_F(PeerConnectionRtpCallbacksTest,
321 UnifiedPlanSetDirectionHoldCallsOnTrackTwice) {
322 auto caller = CreatePeerConnectionWithUnifiedPlan();
323 auto callee = CreatePeerConnectionWithUnifiedPlan();
324
325 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
326
327 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
328 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
329 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
330
331 // Put the call on hold by no longer receiving the track.
332 callee->pc()->GetTransceivers()[0]->SetDirection(
333 RtpTransceiverDirection::kInactive);
334
335 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
336 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
337 EXPECT_EQ(1u, callee->observer()->on_track_transceivers_.size());
338
339 // Resume the call by changing the direction to recvonly. This should call
340 // OnTrack again on the callee side.
341 callee->pc()->GetTransceivers()[0]->SetDirection(
342 RtpTransceiverDirection::kRecvOnly);
343
344 ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
345 EXPECT_EQ(0u, caller->observer()->on_track_transceivers_.size());
346 EXPECT_EQ(2u, callee->observer()->on_track_transceivers_.size());
347}
348
Henrik Boström31638672017-11-23 17:48:32 +0100349// These tests examine the state of the peer connection as a result of
350// performing SetRemoteDescription().
351class PeerConnectionRtpObserverTest : public PeerConnectionRtpTest {};
352
353TEST_F(PeerConnectionRtpObserverTest, AddSenderWithoutStreamAddsReceiver) {
354 auto caller = CreatePeerConnection();
355 auto callee = CreatePeerConnection();
356
Steve Anton2d6c76a2018-01-05 17:10:52 -0800357 ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"), {}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700358 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100359
360 EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
361 auto receiver_added = callee->pc()->GetReceivers()[0];
362 EXPECT_EQ("audio_track", receiver_added->track()->id());
Seth Hampson5b4f0752018-04-02 16:31:36 -0700363 // Since we are not supporting the no stream case with Plan B, there should be
364 // a generated stream, even though we didn't set one with AddTrack.
Henrik Boström31638672017-11-23 17:48:32 +0100365 EXPECT_EQ(receiver_added->streams().size(), 1u);
366 EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
367}
368
369TEST_F(PeerConnectionRtpObserverTest, AddSenderWithStreamAddsReceiver) {
370 auto caller = CreatePeerConnection();
371 auto callee = CreatePeerConnection();
372
Steve Anton2d6c76a2018-01-05 17:10:52 -0800373 ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("audio_track"),
374 {"audio_stream"}));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700375 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100376
377 EXPECT_EQ(callee->pc()->GetReceivers().size(), 1u);
378 auto receiver_added = callee->pc()->GetReceivers()[0];
379 EXPECT_EQ("audio_track", receiver_added->track()->id());
380 EXPECT_EQ(receiver_added->streams().size(), 1u);
Seth Hampson13b8bad2018-03-13 16:05:28 -0700381 EXPECT_EQ("audio_stream", receiver_added->streams()[0]->id());
Henrik Boström31638672017-11-23 17:48:32 +0100382 EXPECT_TRUE(receiver_added->streams()[0]->FindAudioTrack("audio_track"));
383}
384
385TEST_F(PeerConnectionRtpObserverTest,
386 RemoveSenderWithoutStreamRemovesReceiver) {
387 auto caller = CreatePeerConnection();
388 auto callee = CreatePeerConnection();
389
Steve Anton2d6c76a2018-01-05 17:10:52 -0800390 auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
Henrik Boström31638672017-11-23 17:48:32 +0100391 ASSERT_TRUE(sender);
Seth Hampson5897a6e2018-04-03 11:16:33 -0700392 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100393 ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
394 auto receiver = callee->pc()->GetReceivers()[0];
395 ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700396 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100397
398 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
399 // Instead, the transceiver owning the receiver will become inactive.
400 EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
401}
402
403TEST_F(PeerConnectionRtpObserverTest, RemoveSenderWithStreamRemovesReceiver) {
404 auto caller = CreatePeerConnection();
405 auto callee = CreatePeerConnection();
406
Steve Anton2d6c76a2018-01-05 17:10:52 -0800407 auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"),
408 {"audio_stream"});
Henrik Boström31638672017-11-23 17:48:32 +0100409 ASSERT_TRUE(sender);
Seth Hampson5897a6e2018-04-03 11:16:33 -0700410 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100411 ASSERT_EQ(callee->pc()->GetReceivers().size(), 1u);
412 auto receiver = callee->pc()->GetReceivers()[0];
413 ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700414 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100415
416 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
417 // Instead, the transceiver owning the receiver will become inactive.
418 EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
419}
420
421TEST_F(PeerConnectionRtpObserverTest,
422 RemoveSenderWithSharedStreamRemovesReceiver) {
423 auto caller = CreatePeerConnection();
424 auto callee = CreatePeerConnection();
425
Seth Hampson845e8782018-03-02 11:34:10 -0800426 const char kSharedStreamId[] = "shared_audio_stream";
Steve Anton2d6c76a2018-01-05 17:10:52 -0800427 auto sender1 = caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
Seth Hampson845e8782018-03-02 11:34:10 -0800428 {kSharedStreamId});
Steve Anton2d6c76a2018-01-05 17:10:52 -0800429 auto sender2 = caller->AddTrack(caller->CreateAudioTrack("audio_track2"),
Seth Hampson845e8782018-03-02 11:34:10 -0800430 {kSharedStreamId});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700431 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100432
433 ASSERT_EQ(callee->pc()->GetReceivers().size(), 2u);
434 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver1;
435 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver2;
436 if (callee->pc()->GetReceivers()[0]->track()->id() == "audio_track1") {
437 receiver1 = callee->pc()->GetReceivers()[0];
438 receiver2 = callee->pc()->GetReceivers()[1];
439 } else {
440 receiver1 = callee->pc()->GetReceivers()[1];
441 receiver2 = callee->pc()->GetReceivers()[0];
442 }
443 EXPECT_EQ("audio_track1", receiver1->track()->id());
444 EXPECT_EQ("audio_track2", receiver2->track()->id());
445
446 // Remove "audio_track1".
447 EXPECT_TRUE(caller->pc()->RemoveTrack(sender1));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700448 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100449 // Only |receiver2| should remain.
450 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
451 // Instead, the transceiver owning the receiver will become inactive.
452 EXPECT_EQ(
453 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>{receiver2},
454 callee->pc()->GetReceivers());
455
456 // Remove "audio_track2".
457 EXPECT_TRUE(caller->pc()->RemoveTrack(sender2));
Seth Hampson5897a6e2018-04-03 11:16:33 -0700458 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Henrik Boström31638672017-11-23 17:48:32 +0100459 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
460 // Instead, the transceiver owning the receiver will become inactive.
461 EXPECT_EQ(callee->pc()->GetReceivers().size(), 0u);
462}
463
464// Invokes SetRemoteDescription() twice in a row without synchronizing the two
465// calls and examine the state of the peer connection inside the callbacks to
466// ensure that the second call does not occur prematurely, contaminating the
467// state of the peer connection of the first callback.
468TEST_F(PeerConnectionRtpObserverTest,
469 StatesCorrelateWithSetRemoteDescriptionCall) {
470 auto caller = CreatePeerConnection();
471 auto callee = CreatePeerConnection();
472
Henrik Boström31638672017-11-23 17:48:32 +0100473 // Create SDP for adding a track and for removing it. This will be used in the
474 // first and second SetRemoteDescription() calls.
Steve Anton2d6c76a2018-01-05 17:10:52 -0800475 auto sender = caller->AddTrack(caller->CreateAudioTrack("audio_track"), {});
Henrik Boström31638672017-11-23 17:48:32 +0100476 auto srd1_sdp = caller->CreateOfferAndSetAsLocal();
477 EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
478 auto srd2_sdp = caller->CreateOfferAndSetAsLocal();
479
480 // In the first SetRemoteDescription() callback, check that we have a
481 // receiver for the track.
482 auto pc = callee->pc();
483 bool srd1_callback_called = false;
484 auto srd1_callback = [&srd1_callback_called, &pc]() {
485 EXPECT_EQ(pc->GetReceivers().size(), 1u);
486 srd1_callback_called = true;
487 };
488
489 // In the second SetRemoteDescription() callback, check that the receiver has
490 // been removed.
491 // TODO(hbos): When we implement Unified Plan, receivers will not be removed.
492 // Instead, the transceiver owning the receiver will become inactive.
493 // https://crbug.com/webrtc/7600
494 bool srd2_callback_called = false;
495 auto srd2_callback = [&srd2_callback_called, &pc]() {
496 EXPECT_TRUE(pc->GetReceivers().empty());
497 srd2_callback_called = true;
498 };
499
500 // Invoke SetRemoteDescription() twice in a row without synchronizing the two
501 // calls. The callbacks verify that the two calls are synchronized, as in, the
502 // effects of the second SetRemoteDescription() call must not have happened by
503 // the time the first callback is invoked. If it has then the receiver that is
504 // added as a result of the first SetRemoteDescription() call will already
505 // have been removed as a result of the second SetRemoteDescription() call
506 // when the first callback is invoked.
507 callee->pc()->SetRemoteDescription(
508 std::move(srd1_sdp),
509 new OnSuccessObserver<decltype(srd1_callback)>(srd1_callback));
510 callee->pc()->SetRemoteDescription(
511 std::move(srd2_sdp),
512 new OnSuccessObserver<decltype(srd2_callback)>(srd2_callback));
513 EXPECT_TRUE_WAIT(srd1_callback_called, kDefaultTimeout);
514 EXPECT_TRUE_WAIT(srd2_callback_called, kDefaultTimeout);
515}
516
Seth Hampson5897a6e2018-04-03 11:16:33 -0700517// Tests that a remote track is created with the signaled MSIDs when they are
518// communicated with a=msid and no SSRCs are signaled at all (i.e., no a=ssrc
519// lines).
520TEST_F(PeerConnectionRtpObserverTest, UnsignaledSsrcCreatesReceiverStreams) {
521 auto caller = CreatePeerConnectionWithUnifiedPlan();
522 auto callee = CreatePeerConnectionWithUnifiedPlan();
523 const char kStreamId1[] = "stream1";
524 const char kStreamId2[] = "stream2";
525 caller->AddTrack(caller->CreateAudioTrack("audio_track1"),
526 {kStreamId1, kStreamId2});
527
528 auto offer = caller->CreateOfferAndSetAsLocal();
529 // Munge the offer to take out everything but the stream_ids.
530 auto contents = offer->description()->contents();
531 ASSERT_TRUE(!contents.empty());
532 ASSERT_TRUE(!contents[0].media_description()->streams().empty());
533 std::vector<std::string> stream_ids =
534 contents[0].media_description()->streams()[0].stream_ids();
535 contents[0].media_description()->mutable_streams().clear();
536 cricket::StreamParams new_stream;
537 new_stream.set_stream_ids(stream_ids);
538 contents[0].media_description()->AddStream(new_stream);
539
540 // Set the remote description and verify that the streams were added to the
541 // receiver correctly.
542 ASSERT_TRUE(
543 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
544 auto receivers = callee->pc()->GetReceivers();
545 ASSERT_EQ(receivers.size(), 1u);
546 ASSERT_EQ(receivers[0]->streams().size(), 2u);
547 EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId1);
548 EXPECT_EQ(receivers[0]->streams()[1]->id(), kStreamId2);
549}
550
Seth Hampson5b4f0752018-04-02 16:31:36 -0700551// Tests that with Unified Plan if the the stream id changes for a track when
552// when setting a new remote description, that the media stream is updated
553// appropriately for the receiver.
554TEST_F(PeerConnectionRtpObserverTest, RemoteStreamIdChangesUpdatesReceiver) {
555 auto caller = CreatePeerConnectionWithUnifiedPlan();
556 auto callee = CreatePeerConnectionWithUnifiedPlan();
557
558 const char kStreamId1[] = "stream1";
559 const char kStreamId2[] = "stream2";
560 caller->AddTrack(caller->CreateAudioTrack("audio_track1"), {kStreamId1});
Seth Hampson5897a6e2018-04-03 11:16:33 -0700561 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700562 EXPECT_EQ(callee->observer()->add_track_events_.size(), 1u);
563
564 // Change the stream id of the sender in the session description.
565 auto offer = caller->CreateOfferAndSetAsLocal();
566 auto contents = offer->description()->contents();
567 ASSERT_EQ(contents.size(), 1u);
568 ASSERT_EQ(contents[0].media_description()->mutable_streams().size(), 1u);
569 contents[0].media_description()->mutable_streams()[0].set_stream_ids(
570 {kStreamId2});
571
572 // Set the remote description and verify that the stream was updated properly.
573 ASSERT_TRUE(
Seth Hampson5897a6e2018-04-03 11:16:33 -0700574 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
Seth Hampson5b4f0752018-04-02 16:31:36 -0700575 auto receivers = callee->pc()->GetReceivers();
576 ASSERT_EQ(receivers.size(), 1u);
577 ASSERT_EQ(receivers[0]->streams().size(), 1u);
578 EXPECT_EQ(receivers[0]->streams()[0]->id(), kStreamId2);
579}
580
581// This tests a regression caught by a downstream client, that occured when
582// applying a remote description with a SessionDescription object that
583// contained StreamParams that didn't have ids. Although there were multiple
584// remote audio senders, FindSenderInfo didn't find them as unique, because
585// it looked up by StreamParam.id, which none had. This meant only one
586// AudioRtpReceiver was created, as opposed to one for each remote sender.
587TEST_F(PeerConnectionRtpObserverTest,
588 MultipleRemoteSendersWithoutStreamParamIdAddsMultipleReceivers) {
589 auto caller = CreatePeerConnection();
590 auto callee = CreatePeerConnection();
591
592 const char kStreamId1[] = "stream1";
593 const char kStreamId2[] = "stream2";
594 caller->AddAudioTrack("audio_track1", {kStreamId1});
595 caller->AddAudioTrack("audio_track2", {kStreamId2});
596
597 auto offer = caller->CreateOfferAndSetAsLocal();
598 auto mutable_streams =
599 cricket::GetFirstAudioContentDescription(offer->description())
600 ->mutable_streams();
601 ASSERT_EQ(mutable_streams.size(), 2u);
602 // Clear the IDs in the StreamParams.
603 mutable_streams[0].id.clear();
604 mutable_streams[1].id.clear();
605 ASSERT_TRUE(
606 callee->SetRemoteDescription(CloneSessionDescription(offer.get())));
607
608 auto receivers = callee->pc()->GetReceivers();
609 ASSERT_EQ(receivers.size(), 2u);
610 ASSERT_EQ(receivers[0]->streams().size(), 1u);
611 EXPECT_EQ(kStreamId1, receivers[0]->streams()[0]->id());
612 ASSERT_EQ(receivers[1]->streams().size(), 1u);
613 EXPECT_EQ(kStreamId2, receivers[1]->streams()[0]->id());
614}
615
Henrik Boström31638672017-11-23 17:48:32 +0100616// Tests for the legacy SetRemoteDescription() function signature.
617class PeerConnectionRtpLegacyObserverTest : public PeerConnectionRtpTest {};
618
619// Sanity test making sure the callback is invoked.
620TEST_F(PeerConnectionRtpLegacyObserverTest, OnSuccess) {
621 auto caller = CreatePeerConnection();
622 auto callee = CreatePeerConnection();
623
624 std::string error;
625 ASSERT_TRUE(
626 callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal(), &error));
627}
628
629// Verifies legacy behavior: The observer is not called if if the peer
630// connection is destroyed because the asynchronous callback is executed in the
631// peer connection's message handler.
632TEST_F(PeerConnectionRtpLegacyObserverTest,
633 ObserverNotCalledIfPeerConnectionDereferenced) {
634 auto caller = CreatePeerConnection();
635 auto callee = CreatePeerConnection();
636
637 rtc::scoped_refptr<webrtc::MockSetSessionDescriptionObserver> observer =
638 new rtc::RefCountedObject<webrtc::MockSetSessionDescriptionObserver>();
639
640 auto offer = caller->CreateOfferAndSetAsLocal();
641 callee->pc()->SetRemoteDescription(observer, offer.release());
642 callee = nullptr;
643 rtc::Thread::Current()->ProcessMessages(0);
644 EXPECT_FALSE(observer->called());
645}
646
Steve Antonf9381f02017-12-14 10:23:57 -0800647// RtpTransceiver Tests.
Steve Anton9158ef62017-11-27 13:01:52 -0800648
649// Test that by default there are no transceivers with Unified Plan.
650TEST_F(PeerConnectionRtpTest, PeerConnectionHasNoTransceivers) {
651 auto caller = CreatePeerConnectionWithUnifiedPlan();
652 EXPECT_THAT(caller->pc()->GetTransceivers(), ElementsAre());
653}
654
655// Test that a transceiver created with the audio kind has the correct initial
656// properties.
657TEST_F(PeerConnectionRtpTest, AddTransceiverHasCorrectInitProperties) {
658 auto caller = CreatePeerConnectionWithUnifiedPlan();
659
660 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
661 EXPECT_EQ(rtc::nullopt, transceiver->mid());
662 EXPECT_FALSE(transceiver->stopped());
663 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
664 EXPECT_EQ(rtc::nullopt, transceiver->current_direction());
665}
666
667// Test that adding a transceiver with the audio kind creates an audio sender
668// and audio receiver with the receiver having a live audio track.
669TEST_F(PeerConnectionRtpTest,
670 AddAudioTransceiverCreatesAudioSenderAndReceiver) {
671 auto caller = CreatePeerConnectionWithUnifiedPlan();
672
673 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
Steve Anton69470252018-02-09 11:43:08 -0800674 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->media_type());
Steve Anton9158ef62017-11-27 13:01:52 -0800675
676 ASSERT_TRUE(transceiver->sender());
677 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->sender()->media_type());
678
679 ASSERT_TRUE(transceiver->receiver());
680 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, transceiver->receiver()->media_type());
681
682 auto track = transceiver->receiver()->track();
683 ASSERT_TRUE(track);
684 EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, track->kind());
685 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
686}
687
688// Test that adding a transceiver with the video kind creates an video sender
689// and video receiver with the receiver having a live video track.
690TEST_F(PeerConnectionRtpTest,
691 AddAudioTransceiverCreatesVideoSenderAndReceiver) {
692 auto caller = CreatePeerConnectionWithUnifiedPlan();
693
694 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
Steve Anton69470252018-02-09 11:43:08 -0800695 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
Steve Anton9158ef62017-11-27 13:01:52 -0800696
697 ASSERT_TRUE(transceiver->sender());
698 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->sender()->media_type());
699
700 ASSERT_TRUE(transceiver->receiver());
701 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->receiver()->media_type());
702
703 auto track = transceiver->receiver()->track();
704 ASSERT_TRUE(track);
705 EXPECT_EQ(MediaStreamTrackInterface::kVideoKind, track->kind());
706 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive, track->state());
707}
708
709// Test that after a call to AddTransceiver, the transceiver shows in
710// GetTransceivers(), the transceiver's sender shows in GetSenders(), and the
711// transceiver's receiver shows in GetReceivers().
712TEST_F(PeerConnectionRtpTest, AddTransceiverShowsInLists) {
713 auto caller = CreatePeerConnectionWithUnifiedPlan();
714
715 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
716 EXPECT_EQ(
717 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>{transceiver},
718 caller->pc()->GetTransceivers());
719 EXPECT_EQ(
720 std::vector<rtc::scoped_refptr<RtpSenderInterface>>{
721 transceiver->sender()},
722 caller->pc()->GetSenders());
723 EXPECT_EQ(
724 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>{
725 transceiver->receiver()},
726 caller->pc()->GetReceivers());
727}
728
729// Test that the direction passed in through the AddTransceiver init parameter
730// is set in the returned transceiver.
731TEST_F(PeerConnectionRtpTest, AddTransceiverWithDirectionIsReflected) {
732 auto caller = CreatePeerConnectionWithUnifiedPlan();
733
734 RtpTransceiverInit init;
735 init.direction = RtpTransceiverDirection::kSendOnly;
736 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
737 EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
738}
739
Steve Anton9158ef62017-11-27 13:01:52 -0800740// Test that calling AddTransceiver with a track creates a transceiver which has
741// its sender's track set to the passed-in track.
742TEST_F(PeerConnectionRtpTest, AddTransceiverWithTrackCreatesSenderWithTrack) {
743 auto caller = CreatePeerConnectionWithUnifiedPlan();
744
745 auto audio_track = caller->CreateAudioTrack("audio track");
746 auto transceiver = caller->AddTransceiver(audio_track);
747
748 auto sender = transceiver->sender();
749 ASSERT_TRUE(sender->track());
750 EXPECT_EQ(audio_track, sender->track());
751
752 auto receiver = transceiver->receiver();
753 ASSERT_TRUE(receiver->track());
754 EXPECT_EQ(MediaStreamTrackInterface::kAudioKind, receiver->track()->kind());
755 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kLive,
756 receiver->track()->state());
757}
758
759// Test that calling AddTransceiver twice with the same track creates distinct
760// transceivers, senders with the same track.
761TEST_F(PeerConnectionRtpTest,
762 AddTransceiverTwiceWithSameTrackCreatesMultipleTransceivers) {
763 auto caller = CreatePeerConnectionWithUnifiedPlan();
764
765 auto audio_track = caller->CreateAudioTrack("audio track");
766
767 auto transceiver1 = caller->AddTransceiver(audio_track);
768 auto transceiver2 = caller->AddTransceiver(audio_track);
769
770 EXPECT_NE(transceiver1, transceiver2);
771
772 auto sender1 = transceiver1->sender();
773 auto sender2 = transceiver2->sender();
774 EXPECT_NE(sender1, sender2);
775 EXPECT_EQ(audio_track, sender1->track());
776 EXPECT_EQ(audio_track, sender2->track());
777
778 EXPECT_THAT(caller->pc()->GetTransceivers(),
779 UnorderedElementsAre(transceiver1, transceiver2));
780 EXPECT_THAT(caller->pc()->GetSenders(),
781 UnorderedElementsAre(sender1, sender2));
782}
783
Steve Anton3fe1b152017-12-12 10:20:08 -0800784// RtpTransceiver error handling tests.
785
786TEST_F(PeerConnectionRtpTest, AddTransceiverWithInvalidKindReturnsError) {
787 auto caller = CreatePeerConnectionWithUnifiedPlan();
788
789 auto result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_DATA);
790 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
791}
792
793TEST_F(PeerConnectionRtpTest, UnifiedPlanCanClosePeerConnection) {
794 auto caller = CreatePeerConnectionWithUnifiedPlan();
795
796 caller->pc()->Close();
797}
798
Steve Antonf9381f02017-12-14 10:23:57 -0800799// Unified Plan AddTrack tests.
800
801class PeerConnectionRtpUnifiedPlanTest : public PeerConnectionRtpTest {};
802
803// Test that adding an audio track creates a new audio RtpSender with the given
804// track.
805TEST_F(PeerConnectionRtpUnifiedPlanTest, AddAudioTrackCreatesAudioSender) {
806 auto caller = CreatePeerConnectionWithUnifiedPlan();
807
808 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -0800809 auto sender = caller->AddTrack(audio_track);
Steve Antonf9381f02017-12-14 10:23:57 -0800810 ASSERT_TRUE(sender);
811
812 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, sender->media_type());
813 EXPECT_EQ(audio_track, sender->track());
814}
815
816// Test that adding a video track creates a new video RtpSender with the given
817// track.
818TEST_F(PeerConnectionRtpUnifiedPlanTest, AddVideoTrackCreatesVideoSender) {
819 auto caller = CreatePeerConnectionWithUnifiedPlan();
820
821 auto video_track = caller->CreateVideoTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -0800822 auto sender = caller->AddTrack(video_track);
Steve Antonf9381f02017-12-14 10:23:57 -0800823 ASSERT_TRUE(sender);
824
825 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
826 EXPECT_EQ(video_track, sender->track());
827}
828
829// Test that adding a track to a new PeerConnection creates an RtpTransceiver
830// with the sender that AddTrack returns and in the sendrecv direction.
831TEST_F(PeerConnectionRtpUnifiedPlanTest, AddFirstTrackCreatesTransceiver) {
832 auto caller = CreatePeerConnectionWithUnifiedPlan();
833
834 auto sender = caller->AddAudioTrack("a");
835 ASSERT_TRUE(sender);
836
837 auto transceivers = caller->pc()->GetTransceivers();
838 ASSERT_EQ(1u, transceivers.size());
839 EXPECT_EQ(sender, transceivers[0]->sender());
840 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceivers[0]->direction());
841}
842
843// Test that if a transceiver of the same type but no track had been added to
844// the PeerConnection and later a call to AddTrack is made, the resulting sender
845// is the transceiver's sender and the sender's track is the newly-added track.
846TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackReusesTransceiver) {
847 auto caller = CreatePeerConnectionWithUnifiedPlan();
848
849 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
850 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -0800851 auto sender = caller->AddTrack(audio_track);
Steve Antonf9381f02017-12-14 10:23:57 -0800852 ASSERT_TRUE(sender);
853
854 auto transceivers = caller->pc()->GetTransceivers();
855 ASSERT_EQ(1u, transceivers.size());
856 EXPECT_EQ(transceiver, transceivers[0]);
857 EXPECT_EQ(sender, transceiver->sender());
858 EXPECT_EQ(audio_track, sender->track());
859}
860
861// Test that adding two tracks to a new PeerConnection creates two
862// RtpTransceivers in the same order.
863TEST_F(PeerConnectionRtpUnifiedPlanTest, TwoAddTrackCreatesTwoTransceivers) {
864 auto caller = CreatePeerConnectionWithUnifiedPlan();
865
866 auto sender1 = caller->AddAudioTrack("a");
867 auto sender2 = caller->AddVideoTrack("v");
868 ASSERT_TRUE(sender2);
869
870 auto transceivers = caller->pc()->GetTransceivers();
871 ASSERT_EQ(2u, transceivers.size());
872 EXPECT_EQ(sender1, transceivers[0]->sender());
873 EXPECT_EQ(sender2, transceivers[1]->sender());
874}
875
876// Test that if there are multiple transceivers with no sending track then a
877// later call to AddTrack will use the one of the same type as the newly-added
878// track.
879TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackReusesTransceiverOfType) {
880 auto caller = CreatePeerConnectionWithUnifiedPlan();
881
882 auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
883 auto video_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
884 auto sender = caller->AddVideoTrack("v");
885
886 ASSERT_EQ(2u, caller->pc()->GetTransceivers().size());
887 EXPECT_NE(sender, audio_transceiver->sender());
888 EXPECT_EQ(sender, video_transceiver->sender());
889}
890
891// Test that if the only transceivers that do not have a sending track have a
892// different type from the added track, then AddTrack will create a new
893// transceiver for the track.
894TEST_F(PeerConnectionRtpUnifiedPlanTest,
895 AddTrackDoesNotReuseTransceiverOfWrongType) {
896 auto caller = CreatePeerConnectionWithUnifiedPlan();
897
898 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
899 auto sender = caller->AddVideoTrack("v");
900
901 auto transceivers = caller->pc()->GetTransceivers();
902 ASSERT_EQ(2u, transceivers.size());
903 EXPECT_NE(sender, transceivers[0]->sender());
904 EXPECT_EQ(sender, transceivers[1]->sender());
905}
906
907// Test that the first available transceiver is reused by AddTrack when multiple
908// are available.
909TEST_F(PeerConnectionRtpUnifiedPlanTest,
910 AddTrackReusesFirstMatchingTransceiver) {
911 auto caller = CreatePeerConnectionWithUnifiedPlan();
912
913 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
914 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
915 auto sender = caller->AddAudioTrack("a");
916
917 auto transceivers = caller->pc()->GetTransceivers();
918 ASSERT_EQ(2u, transceivers.size());
919 EXPECT_EQ(sender, transceivers[0]->sender());
920 EXPECT_NE(sender, transceivers[1]->sender());
921}
922
923// Test that a call to AddTrack that reuses a transceiver will change the
924// direction from inactive to sendonly.
925TEST_F(PeerConnectionRtpUnifiedPlanTest,
926 AddTrackChangesDirectionFromInactiveToSendOnly) {
927 auto caller = CreatePeerConnectionWithUnifiedPlan();
928
929 RtpTransceiverInit init;
930 init.direction = RtpTransceiverDirection::kInactive;
931 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
932
933 caller->observer()->clear_negotiation_needed();
934 ASSERT_TRUE(caller->AddAudioTrack("a"));
935 EXPECT_TRUE(caller->observer()->negotiation_needed());
936
937 EXPECT_EQ(RtpTransceiverDirection::kSendOnly, transceiver->direction());
938}
939
940// Test that a call to AddTrack that reuses a transceiver will change the
941// direction from recvonly to sendrecv.
942TEST_F(PeerConnectionRtpUnifiedPlanTest,
943 AddTrackChangesDirectionFromRecvOnlyToSendRecv) {
944 auto caller = CreatePeerConnectionWithUnifiedPlan();
945
946 RtpTransceiverInit init;
947 init.direction = RtpTransceiverDirection::kRecvOnly;
948 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
949
950 caller->observer()->clear_negotiation_needed();
951 ASSERT_TRUE(caller->AddAudioTrack("a"));
952 EXPECT_TRUE(caller->observer()->negotiation_needed());
953
954 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
955}
956
Steve Anton02ee47c2018-01-10 16:26:06 -0800957TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackCreatesSenderWithTrackId) {
958 const std::string kTrackId = "audio_track";
959
960 auto caller = CreatePeerConnectionWithUnifiedPlan();
961
962 auto audio_track = caller->CreateAudioTrack(kTrackId);
963 auto sender = caller->AddTrack(audio_track);
964
965 EXPECT_EQ(kTrackId, sender->id());
966}
967
Steve Antonf9381f02017-12-14 10:23:57 -0800968// Unified Plan AddTrack error handling.
969
970TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackErrorIfClosed) {
971 auto caller = CreatePeerConnectionWithUnifiedPlan();
972
973 auto audio_track = caller->CreateAudioTrack("a");
974 caller->pc()->Close();
975
976 caller->observer()->clear_negotiation_needed();
Steve Anton2d6c76a2018-01-05 17:10:52 -0800977 auto result = caller->pc()
978 ->AddTrack(audio_track, std::vector<std::string>());
979 EXPECT_EQ(RTCErrorType::INVALID_STATE, result.error().type());
Steve Antonf9381f02017-12-14 10:23:57 -0800980 EXPECT_FALSE(caller->observer()->negotiation_needed());
981}
982
983TEST_F(PeerConnectionRtpUnifiedPlanTest, AddTrackErrorIfTrackAlreadyHasSender) {
984 auto caller = CreatePeerConnectionWithUnifiedPlan();
985
986 auto audio_track = caller->CreateAudioTrack("a");
Steve Anton2d6c76a2018-01-05 17:10:52 -0800987 ASSERT_TRUE(caller->AddTrack(audio_track));
Steve Antonf9381f02017-12-14 10:23:57 -0800988
989 caller->observer()->clear_negotiation_needed();
Steve Anton2d6c76a2018-01-05 17:10:52 -0800990 auto result = caller->pc()
991 ->AddTrack(audio_track, std::vector<std::string>());
992 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Steve Antonf9381f02017-12-14 10:23:57 -0800993 EXPECT_FALSE(caller->observer()->negotiation_needed());
994}
995
996// Unified Plan RemoveTrack tests.
997
998// Test that calling RemoveTrack on a sender with a previously-added track
999// clears the sender's track.
1000TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackClearsSenderTrack) {
1001 auto caller = CreatePeerConnectionWithUnifiedPlan();
1002
1003 auto sender = caller->AddAudioTrack("a");
1004 ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
1005
1006 EXPECT_FALSE(sender->track());
1007}
1008
1009// Test that calling RemoveTrack on a sender where the transceiver is configured
1010// in the sendrecv direction changes the transceiver's direction to recvonly.
1011TEST_F(PeerConnectionRtpUnifiedPlanTest,
1012 RemoveTrackChangesDirectionFromSendRecvToRecvOnly) {
1013 auto caller = CreatePeerConnectionWithUnifiedPlan();
1014
1015 RtpTransceiverInit init;
1016 init.direction = RtpTransceiverDirection::kSendRecv;
1017 auto transceiver =
1018 caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
1019
1020 caller->observer()->clear_negotiation_needed();
1021 ASSERT_TRUE(caller->pc()->RemoveTrack(transceiver->sender()));
1022 EXPECT_TRUE(caller->observer()->negotiation_needed());
1023
1024 EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceiver->direction());
1025 EXPECT_TRUE(caller->observer()->renegotiation_needed_);
1026}
1027
1028// Test that calling RemoveTrack on a sender where the transceiver is configured
1029// in the sendonly direction changes the transceiver's direction to inactive.
1030TEST_F(PeerConnectionRtpUnifiedPlanTest,
1031 RemoveTrackChangesDirectionFromSendOnlyToInactive) {
1032 auto caller = CreatePeerConnectionWithUnifiedPlan();
1033
1034 RtpTransceiverInit init;
1035 init.direction = RtpTransceiverDirection::kSendOnly;
1036 auto transceiver =
1037 caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
1038
1039 caller->observer()->clear_negotiation_needed();
1040 ASSERT_TRUE(caller->pc()->RemoveTrack(transceiver->sender()));
1041 EXPECT_TRUE(caller->observer()->negotiation_needed());
1042
1043 EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver->direction());
1044}
1045
1046// Test that calling RemoveTrack with a sender that has a null track results in
1047// no change in state.
1048TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackWithNullSenderTrackIsNoOp) {
1049 auto caller = CreatePeerConnectionWithUnifiedPlan();
1050
1051 auto sender = caller->AddAudioTrack("a");
1052 auto transceiver = caller->pc()->GetTransceivers()[0];
1053 ASSERT_TRUE(sender->SetTrack(nullptr));
1054
1055 caller->observer()->clear_negotiation_needed();
1056 ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
1057 EXPECT_FALSE(caller->observer()->negotiation_needed());
1058
1059 EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
1060}
1061
1062// Unified Plan RemoveTrack error handling.
1063
1064TEST_F(PeerConnectionRtpUnifiedPlanTest, RemoveTrackErrorIfClosed) {
1065 auto caller = CreatePeerConnectionWithUnifiedPlan();
1066
1067 auto sender = caller->AddAudioTrack("a");
1068 caller->pc()->Close();
1069
1070 caller->observer()->clear_negotiation_needed();
1071 EXPECT_FALSE(caller->pc()->RemoveTrack(sender));
1072 EXPECT_FALSE(caller->observer()->negotiation_needed());
1073}
1074
1075TEST_F(PeerConnectionRtpUnifiedPlanTest,
1076 RemoveTrackNoErrorIfTrackAlreadyRemoved) {
1077 auto caller = CreatePeerConnectionWithUnifiedPlan();
1078
1079 auto sender = caller->AddAudioTrack("a");
1080 ASSERT_TRUE(caller->pc()->RemoveTrack(sender));
1081
1082 caller->observer()->clear_negotiation_needed();
1083 EXPECT_TRUE(caller->pc()->RemoveTrack(sender));
1084 EXPECT_FALSE(caller->observer()->negotiation_needed());
1085}
1086
Steve Anton52d86772018-02-20 15:48:12 -08001087// Test that OnRenegotiationNeeded is fired if SetDirection is called on an
1088// active RtpTransceiver with a new direction.
1089TEST_F(PeerConnectionRtpUnifiedPlanTest,
1090 RenegotiationNeededAfterTransceiverSetDirection) {
1091 auto caller = CreatePeerConnectionWithUnifiedPlan();
1092
1093 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1094
1095 caller->observer()->clear_negotiation_needed();
1096 transceiver->SetDirection(RtpTransceiverDirection::kInactive);
1097 EXPECT_TRUE(caller->observer()->negotiation_needed());
1098}
1099
1100// Test that OnRenegotiationNeeded is not fired if SetDirection is called on an
1101// active RtpTransceiver with current direction.
1102TEST_F(PeerConnectionRtpUnifiedPlanTest,
1103 NoRenegotiationNeededAfterTransceiverSetSameDirection) {
1104 auto caller = CreatePeerConnectionWithUnifiedPlan();
1105
1106 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1107
1108 caller->observer()->clear_negotiation_needed();
1109 transceiver->SetDirection(transceiver->direction());
1110 EXPECT_FALSE(caller->observer()->negotiation_needed());
1111}
1112
1113// Test that OnRenegotiationNeeded is not fired if SetDirection is called on a
1114// stopped RtpTransceiver.
1115TEST_F(PeerConnectionRtpUnifiedPlanTest,
1116 NoRenegotiationNeededAfterSetDirectionOnStoppedTransceiver) {
1117 auto caller = CreatePeerConnectionWithUnifiedPlan();
1118
1119 auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
1120 transceiver->Stop();
1121
1122 caller->observer()->clear_negotiation_needed();
1123 transceiver->SetDirection(RtpTransceiverDirection::kInactive);
1124 EXPECT_FALSE(caller->observer()->negotiation_needed());
1125}
1126
Steve Antone831b8c2018-02-01 12:22:16 -08001127// Test MSID signaling between Unified Plan and Plan B endpoints. There are two
1128// options for this kind of signaling: media section based (a=msid) and ssrc
1129// based (a=ssrc MSID). While JSEP only specifies media section MSID signaling,
1130// we want to ensure compatibility with older Plan B endpoints that might expect
1131// ssrc based MSID signaling. Thus we test here that Unified Plan offers both
1132// types but answers with the same type as the offer.
1133
1134class PeerConnectionMsidSignalingTest : public PeerConnectionRtpTest {};
1135
1136TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanTalkingToOurself) {
1137 auto caller = CreatePeerConnectionWithUnifiedPlan();
1138 caller->AddAudioTrack("caller_audio");
1139 auto callee = CreatePeerConnectionWithUnifiedPlan();
1140 callee->AddAudioTrack("callee_audio");
Steve Anton8e20f172018-03-06 10:55:04 -08001141 auto caller_observer = caller->RegisterFakeMetricsObserver();
Steve Antone831b8c2018-02-01 12:22:16 -08001142
1143 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1144
1145 // Offer should have had both a=msid and a=ssrc MSID lines.
1146 auto* offer = callee->pc()->remote_description();
1147 EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1148 cricket::kMsidSignalingSsrcAttribute),
1149 offer->description()->msid_signaling());
1150
1151 // Answer should have had only a=msid lines.
1152 auto* answer = caller->pc()->remote_description();
1153 EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1154 answer->description()->msid_signaling());
Harald Alvestrand5dbb5862018-02-13 23:48:00 +01001155 // Check that this is counted correctly
Steve Anton8e20f172018-03-06 10:55:04 -08001156 EXPECT_TRUE(caller_observer->ExpectOnlySingleEnumCount(
1157 kEnumCounterSdpSemanticNegotiated, kSdpSemanticNegotiatedUnifiedPlan));
Steve Antone831b8c2018-02-01 12:22:16 -08001158}
1159
1160TEST_F(PeerConnectionMsidSignalingTest, PlanBOfferToUnifiedPlanAnswer) {
1161 auto caller = CreatePeerConnectionWithPlanB();
1162 caller->AddAudioTrack("caller_audio");
1163 auto callee = CreatePeerConnectionWithUnifiedPlan();
1164 callee->AddAudioTrack("callee_audio");
1165
1166 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1167
1168 // Offer should have only a=ssrc MSID lines.
1169 auto* offer = callee->pc()->remote_description();
1170 EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1171 offer->description()->msid_signaling());
1172
1173 // Answer should have only a=ssrc MSID lines to match the offer.
1174 auto* answer = caller->pc()->remote_description();
1175 EXPECT_EQ(cricket::kMsidSignalingSsrcAttribute,
1176 answer->description()->msid_signaling());
1177}
1178
Seth Hampson5b4f0752018-04-02 16:31:36 -07001179// This tests that a Plan B endpoint appropriately sets the remote description
1180// from a Unified Plan offer. When the Unified Plan offer contains a=msid lines
1181// that signal no stream ids or multiple stream ids we expect that the Plan B
1182// endpoint always has exactly one media stream per track.
1183TEST_F(PeerConnectionMsidSignalingTest, UnifiedPlanToPlanBAnswer) {
1184 const std::string kStreamId1 = "audio_stream_1";
1185 const std::string kStreamId2 = "audio_stream_2";
1186
1187 auto caller = CreatePeerConnectionWithUnifiedPlan();
1188 caller->AddAudioTrack("caller_audio", {kStreamId1, kStreamId2});
1189 caller->AddVideoTrack("caller_video", {});
1190 auto callee = CreatePeerConnectionWithPlanB();
1191 callee->AddAudioTrack("callee_audio");
1192 caller->AddVideoTrack("callee_video");
1193
1194 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1195
1196 // Offer should have had both a=msid and a=ssrc MSID lines.
1197 auto* offer = callee->pc()->remote_description();
1198 EXPECT_EQ((cricket::kMsidSignalingMediaSection |
1199 cricket::kMsidSignalingSsrcAttribute),
1200 offer->description()->msid_signaling());
1201
1202 // Callee should always have 1 stream for all of it's receivers.
1203 const auto& track_events = callee->observer()->add_track_events_;
1204 ASSERT_EQ(2u, track_events.size());
1205 ASSERT_EQ(1u, track_events[0].streams.size());
1206 EXPECT_EQ(kStreamId1, track_events[0].streams[0]->id());
1207 ASSERT_EQ(1u, track_events[1].streams.size());
1208 // This autogenerated a stream id for the empty one signalled.
1209 EXPECT_FALSE(track_events[1].streams[0]->id().empty());
1210}
1211
Steve Antone831b8c2018-02-01 12:22:16 -08001212TEST_F(PeerConnectionMsidSignalingTest, PureUnifiedPlanToUs) {
1213 auto caller = CreatePeerConnectionWithUnifiedPlan();
1214 caller->AddAudioTrack("caller_audio");
1215 auto callee = CreatePeerConnectionWithUnifiedPlan();
1216 callee->AddAudioTrack("callee_audio");
1217
1218 auto offer = caller->CreateOffer();
1219 // Simulate a pure Unified Plan offerer by setting the MSID signaling to media
1220 // section only.
1221 offer->description()->set_msid_signaling(cricket::kMsidSignalingMediaSection);
1222
1223 ASSERT_TRUE(
1224 caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1225 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1226
1227 // Answer should have only a=msid to match the offer.
1228 auto answer = callee->CreateAnswer();
1229 EXPECT_EQ(cricket::kMsidSignalingMediaSection,
1230 answer->description()->msid_signaling());
1231}
1232
Steve Anton8e20f172018-03-06 10:55:04 -08001233// Test that the correct UMA metrics are reported for simple/complex SDP.
1234
1235class SdpFormatReceivedTest : public PeerConnectionRtpTest {};
1236
1237#ifdef HAVE_SCTP
1238TEST_F(SdpFormatReceivedTest, DataChannelOnlyIsReportedAsNoTracks) {
1239 auto caller = CreatePeerConnectionWithUnifiedPlan();
1240 caller->CreateDataChannel("dc");
1241 auto callee = CreatePeerConnectionWithUnifiedPlan();
1242 auto callee_metrics = callee->RegisterFakeMetricsObserver();
1243
1244 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1245
1246 EXPECT_TRUE(callee_metrics->ExpectOnlySingleEnumCount(
1247 kEnumCounterSdpFormatReceived, kSdpFormatReceivedNoTracks));
1248}
1249#endif // HAVE_SCTP
1250
1251TEST_F(SdpFormatReceivedTest, SimpleUnifiedPlanIsReportedAsSimple) {
1252 auto caller = CreatePeerConnectionWithUnifiedPlan();
1253 caller->AddAudioTrack("audio");
1254 caller->AddVideoTrack("video");
1255 auto callee = CreatePeerConnectionWithPlanB();
1256 auto callee_metrics = callee->RegisterFakeMetricsObserver();
1257
1258 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1259
1260 EXPECT_TRUE(callee_metrics->ExpectOnlySingleEnumCount(
1261 kEnumCounterSdpFormatReceived, kSdpFormatReceivedSimple));
1262}
1263
1264TEST_F(SdpFormatReceivedTest, SimplePlanBIsReportedAsSimple) {
1265 auto caller = CreatePeerConnectionWithPlanB();
1266 caller->AddVideoTrack("video"); // Video only.
1267 auto callee = CreatePeerConnectionWithUnifiedPlan();
1268 auto callee_metrics = callee->RegisterFakeMetricsObserver();
1269
1270 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1271
1272 EXPECT_TRUE(callee_metrics->ExpectOnlySingleEnumCount(
1273 kEnumCounterSdpFormatReceived, kSdpFormatReceivedSimple));
1274}
1275
1276TEST_F(SdpFormatReceivedTest, ComplexUnifiedIsReportedAsComplexUnifiedPlan) {
1277 auto caller = CreatePeerConnectionWithUnifiedPlan();
1278 caller->AddAudioTrack("audio1");
1279 caller->AddAudioTrack("audio2");
1280 caller->AddVideoTrack("video");
1281 auto callee = CreatePeerConnectionWithPlanB();
1282 auto callee_metrics = callee->RegisterFakeMetricsObserver();
1283
1284 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
1285
1286 EXPECT_TRUE(callee_metrics->ExpectOnlySingleEnumCount(
1287 kEnumCounterSdpFormatReceived, kSdpFormatReceivedComplexUnifiedPlan));
1288}
1289
1290TEST_F(SdpFormatReceivedTest, ComplexPlanBIsReportedAsComplexPlanB) {
1291 auto caller = CreatePeerConnectionWithPlanB();
1292 caller->AddVideoTrack("video1");
1293 caller->AddVideoTrack("video2");
1294 auto callee = CreatePeerConnectionWithUnifiedPlan();
1295 auto callee_metrics = callee->RegisterFakeMetricsObserver();
1296
Steve Antonba42e992018-04-09 14:10:01 -07001297 // This fails since Unified Plan cannot set a session description with
1298 // multiple "Plan B tracks" in the same media section. But we still expect the
1299 // SDP Format to be recorded.
1300 ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer()));
Steve Anton8e20f172018-03-06 10:55:04 -08001301
1302 EXPECT_TRUE(callee_metrics->ExpectOnlySingleEnumCount(
1303 kEnumCounterSdpFormatReceived, kSdpFormatReceivedComplexPlanB));
1304}
1305
Henrik Boström91d039b2018-01-11 17:43:30 +01001306// Sender setups in a call.
1307
1308class PeerConnectionSenderTest : public PeerConnectionRtpTest {};
1309
1310TEST_F(PeerConnectionSenderTest, CreateTwoSendersWithSameTrack) {
1311 auto caller = CreatePeerConnection();
1312 auto callee = CreatePeerConnection();
1313
1314 auto track = caller->CreateAudioTrack("audio_track");
1315 auto sender1 = caller->AddTrack(track);
1316 ASSERT_TRUE(sender1);
1317 // We need to temporarily reset the track for the subsequent AddTrack() to
1318 // succeed.
1319 EXPECT_TRUE(sender1->SetTrack(nullptr));
1320 auto sender2 = caller->AddTrack(track);
1321 EXPECT_TRUE(sender2);
1322 EXPECT_TRUE(sender1->SetTrack(track));
1323
1324 // TODO(hbos): When https://crbug.com/webrtc/8734 is resolved, this should
1325 // return true, and doing |callee->SetRemoteDescription()| should work.
1326 EXPECT_FALSE(caller->CreateOfferAndSetAsLocal());
1327}
1328
Steve Anton9158ef62017-11-27 13:01:52 -08001329} // namespace webrtc