1 /*
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 // This file contains tests that check the PeerConnection's signaling state
12 // machine, as well as tests that check basic, media-agnostic aspects of SDP.
13
14 #include <algorithm>
15 #include <cstdint>
16 #include <functional>
17 #include <map>
18 #include <memory>
19 #include <set>
20 #include <string>
21 #include <tuple>
22 #include <type_traits>
23 #include <utility>
24 #include <vector>
25
26 #include "absl/types/optional.h"
27 #include "api/audio/audio_mixer.h"
28 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
29 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
30 #include "api/create_peerconnection_factory.h"
31 #include "api/dtls_transport_interface.h"
32 #include "api/jsep.h"
33 #include "api/media_types.h"
34 #include "api/peer_connection_interface.h"
35 #include "api/rtc_error.h"
36 #include "api/rtp_receiver_interface.h"
37 #include "api/rtp_sender_interface.h"
38 #include "api/rtp_transceiver_interface.h"
39 #include "api/scoped_refptr.h"
40 #include "api/set_local_description_observer_interface.h"
41 #include "api/set_remote_description_observer_interface.h"
42 #include "api/video_codecs/builtin_video_decoder_factory.h"
43 #include "api/video_codecs/builtin_video_encoder_factory.h"
44 #include "media/base/codec.h"
45 #include "modules/audio_device/include/audio_device.h"
46 #include "modules/audio_processing/include/audio_processing.h"
47 #include "p2p/base/port_allocator.h"
48 #include "pc/peer_connection.h"
49 #include "pc/peer_connection_proxy.h"
50 #include "pc/peer_connection_wrapper.h"
51 #include "pc/sdp_utils.h"
52 #include "pc/session_description.h"
53 #include "pc/test/mock_peer_connection_observers.h"
54 #include "rtc_base/checks.h"
55 #include "rtc_base/rtc_certificate.h"
56 #include "rtc_base/rtc_certificate_generator.h"
57 #include "rtc_base/string_encode.h"
58 #include "rtc_base/thread.h"
59 #include "test/gtest.h"
60 #ifdef WEBRTC_ANDROID
61 #include "pc/test/android_test_initializer.h"
62 #endif
63 #include "pc/test/fake_audio_capture_module.h"
64 #include "pc/test/fake_rtc_certificate_generator.h"
65 #include "rtc_base/gunit.h"
66 #include "rtc_base/virtual_socket_server.h"
67
68 namespace webrtc {
69
70 using SignalingState = PeerConnectionInterface::SignalingState;
71 using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
72 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
73 using ::testing::Bool;
74 using ::testing::Combine;
75 using ::testing::Values;
76
77 namespace {
78 const int64_t kWaitTimeout = 10000;
79 } // namespace
80
81 class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
82 public:
83 using PeerConnectionWrapper::PeerConnectionWrapper;
84
initial_offerer()85 bool initial_offerer() {
86 return GetInternalPeerConnection()->initial_offerer();
87 }
88
GetInternalPeerConnection()89 PeerConnection* GetInternalPeerConnection() {
90 auto* pci =
91 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
92 pc());
93 return static_cast<PeerConnection*>(pci->internal());
94 }
95 };
96
97 class ExecuteFunctionOnCreateSessionDescriptionObserver
98 : public CreateSessionDescriptionObserver {
99 public:
ExecuteFunctionOnCreateSessionDescriptionObserver(std::function<void (SessionDescriptionInterface *)> function)100 ExecuteFunctionOnCreateSessionDescriptionObserver(
101 std::function<void(SessionDescriptionInterface*)> function)
102 : function_(std::move(function)) {}
~ExecuteFunctionOnCreateSessionDescriptionObserver()103 ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
104 RTC_DCHECK(was_called_);
105 }
106
was_called() const107 bool was_called() const { return was_called_; }
108
OnSuccess(SessionDescriptionInterface * desc)109 void OnSuccess(SessionDescriptionInterface* desc) override {
110 RTC_DCHECK(!was_called_);
111 was_called_ = true;
112 function_(desc);
113 }
114
OnFailure(RTCError error)115 void OnFailure(RTCError error) override { RTC_DCHECK_NOTREACHED(); }
116
117 private:
118 bool was_called_ = false;
119 std::function<void(SessionDescriptionInterface*)> function_;
120 };
121
122 class PeerConnectionSignalingBaseTest : public ::testing::Test {
123 protected:
124 typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
125
PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)126 explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
127 : vss_(new rtc::VirtualSocketServer()),
128 main_(vss_.get()),
129 sdp_semantics_(sdp_semantics) {
130 #ifdef WEBRTC_ANDROID
131 InitializeAndroidObjects();
132 #endif
133 pc_factory_ = CreatePeerConnectionFactory(
134 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
135 rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
136 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
137 CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
138 nullptr /* audio_mixer */, nullptr /* audio_processing */);
139 }
140
CreatePeerConnection()141 WrapperPtr CreatePeerConnection() {
142 return CreatePeerConnection(RTCConfiguration());
143 }
144
CreatePeerConnection(const RTCConfiguration & config)145 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
146 auto observer = std::make_unique<MockPeerConnectionObserver>();
147 RTCConfiguration modified_config = config;
148 modified_config.sdp_semantics = sdp_semantics_;
149 auto result = pc_factory_->CreatePeerConnectionOrError(
150 modified_config, PeerConnectionDependencies(observer.get()));
151 if (!result.ok()) {
152 return nullptr;
153 }
154
155 observer->SetPeerConnectionInterface(result.value().get());
156 return std::make_unique<PeerConnectionWrapperForSignalingTest>(
157 pc_factory_, result.MoveValue(), std::move(observer));
158 }
159
160 // Accepts the same arguments as CreatePeerConnection and adds default audio
161 // and video tracks.
162 template <typename... Args>
CreatePeerConnectionWithAudioVideo(Args &&...args)163 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
164 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
165 if (!wrapper) {
166 return nullptr;
167 }
168 wrapper->AddAudioTrack("a");
169 wrapper->AddVideoTrack("v");
170 return wrapper;
171 }
172
NumberOfDtlsTransports(const WrapperPtr & pc_wrapper)173 int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
174 std::set<DtlsTransportInterface*> transports;
175 auto transceivers = pc_wrapper->pc()->GetTransceivers();
176
177 for (auto& transceiver : transceivers) {
178 if (transceiver->sender()->dtls_transport()) {
179 EXPECT_TRUE(transceiver->receiver()->dtls_transport());
180 EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
181 transceiver->receiver()->dtls_transport().get());
182 transports.insert(transceiver->sender()->dtls_transport().get());
183 } else {
184 // If one transceiver is missing, they all should be.
185 EXPECT_EQ(0UL, transports.size());
186 }
187 }
188 return transports.size();
189 }
190
HasDtlsTransport(const WrapperPtr & pc_wrapper)191 bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
192 return NumberOfDtlsTransports(pc_wrapper) > 0;
193 }
194
195 std::unique_ptr<rtc::VirtualSocketServer> vss_;
196 rtc::AutoSocketServerThread main_;
197 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
198 const SdpSemantics sdp_semantics_;
199 };
200
201 class PeerConnectionSignalingTest
202 : public PeerConnectionSignalingBaseTest,
203 public ::testing::WithParamInterface<SdpSemantics> {
204 protected:
PeerConnectionSignalingTest()205 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
206 };
207
TEST_P(PeerConnectionSignalingTest,SetLocalOfferTwiceWorks)208 TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
209 auto caller = CreatePeerConnection();
210
211 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
212 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
213 }
214
TEST_P(PeerConnectionSignalingTest,SetRemoteOfferTwiceWorks)215 TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
216 auto caller = CreatePeerConnection();
217 auto callee = CreatePeerConnection();
218
219 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
220 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
221 }
222
TEST_P(PeerConnectionSignalingTest,FailToSetNullLocalDescription)223 TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
224 auto caller = CreatePeerConnection();
225 std::string error;
226 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
227 EXPECT_EQ("SessionDescription is NULL.", error);
228 }
229
TEST_P(PeerConnectionSignalingTest,FailToSetNullRemoteDescription)230 TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
231 auto caller = CreatePeerConnection();
232 std::string error;
233 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
234 EXPECT_EQ("SessionDescription is NULL.", error);
235 }
236
237 // The following parameterized test verifies that calls to various signaling
238 // methods on PeerConnection will succeed/fail depending on what is the
239 // PeerConnection's signaling state. Note that the test tries many different
240 // forms of SignalingState::kClosed by arriving at a valid state then calling
241 // `Close()`. This is intended to catch cases where the PeerConnection signaling
242 // method ignores the closed flag but may work/not work because of the single
243 // state the PeerConnection was created in before it was closed.
244
245 class PeerConnectionSignalingStateTest
246 : public PeerConnectionSignalingBaseTest,
247 public ::testing::WithParamInterface<
248 std::tuple<SdpSemantics, SignalingState, bool>> {
249 protected:
PeerConnectionSignalingStateTest()250 PeerConnectionSignalingStateTest()
251 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
252 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
253 std::get<2>(GetParam()))) {}
254
GetConfig()255 RTCConfiguration GetConfig() {
256 RTCConfiguration config;
257 config.certificates.push_back(
258 FakeRTCCertificateGenerator::GenerateCertificate());
259 return config;
260 }
261
CreatePeerConnectionUnderTest()262 WrapperPtr CreatePeerConnectionUnderTest() {
263 return CreatePeerConnectionInState(state_under_test_);
264 }
265
CreatePeerConnectionInState(SignalingState state)266 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
267 return CreatePeerConnectionInState(std::make_tuple(state, false));
268 }
269
CreatePeerConnectionInState(std::tuple<SignalingState,bool> state_tuple)270 WrapperPtr CreatePeerConnectionInState(
271 std::tuple<SignalingState, bool> state_tuple) {
272 SignalingState state = std::get<0>(state_tuple);
273 bool closed = std::get<1>(state_tuple);
274
275 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
276 switch (state) {
277 case SignalingState::kStable: {
278 break;
279 }
280 case SignalingState::kHaveLocalOffer: {
281 wrapper->SetLocalDescription(wrapper->CreateOffer());
282 break;
283 }
284 case SignalingState::kHaveLocalPrAnswer: {
285 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
286 wrapper->SetRemoteDescription(caller->CreateOffer());
287 auto answer = wrapper->CreateAnswer();
288 wrapper->SetLocalDescription(
289 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
290 break;
291 }
292 case SignalingState::kHaveRemoteOffer: {
293 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
294 wrapper->SetRemoteDescription(caller->CreateOffer());
295 break;
296 }
297 case SignalingState::kHaveRemotePrAnswer: {
298 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
299 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
300 auto answer = callee->CreateAnswer();
301 wrapper->SetRemoteDescription(
302 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
303 break;
304 }
305 case SignalingState::kClosed: {
306 RTC_DCHECK_NOTREACHED()
307 << "Set the second member of the tuple to true to "
308 "achieve a closed state from an existing, valid "
309 "state.";
310 }
311 }
312
313 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
314
315 if (closed) {
316 wrapper->pc()->Close();
317 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
318 }
319
320 return wrapper;
321 }
322
323 std::tuple<SignalingState, bool> state_under_test_;
324 };
325
TEST_P(PeerConnectionSignalingStateTest,CreateOffer)326 TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
327 auto wrapper = CreatePeerConnectionUnderTest();
328 if (wrapper->signaling_state() != SignalingState::kClosed) {
329 EXPECT_TRUE(wrapper->CreateOffer());
330 } else {
331 std::string error;
332 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
333 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
334 "CreateOffer called when PeerConnection is closed.");
335 }
336 }
337
TEST_P(PeerConnectionSignalingStateTest,CreateAnswer)338 TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
339 auto wrapper = CreatePeerConnectionUnderTest();
340 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
341 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
342 EXPECT_TRUE(wrapper->CreateAnswer());
343 } else {
344 std::string error;
345 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
346 EXPECT_EQ(error,
347 "PeerConnection cannot create an answer in a state other than "
348 "have-remote-offer or have-local-pranswer.");
349 }
350 }
351
TEST_P(PeerConnectionSignalingStateTest,SetLocalOffer)352 TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
353 auto wrapper = CreatePeerConnectionUnderTest();
354 if (wrapper->signaling_state() == SignalingState::kStable ||
355 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
356 // Need to call CreateOffer on the PeerConnection under test, otherwise when
357 // setting the local offer it will want to verify the DTLS fingerprint
358 // against the locally generated certificate, but without a call to
359 // CreateOffer the certificate will never be generated.
360 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
361 } else {
362 auto wrapper_for_offer =
363 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
364 auto offer =
365 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
366
367 std::string error;
368 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
369 EXPECT_PRED_FORMAT2(
370 AssertStartsWith, error,
371 "Failed to set local offer sdp: Called in wrong state:");
372 }
373 }
374
TEST_P(PeerConnectionSignalingStateTest,SetLocalPrAnswer)375 TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
376 auto wrapper_for_pranswer =
377 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
378 auto pranswer =
379 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
380
381 auto wrapper = CreatePeerConnectionUnderTest();
382 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
383 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
384 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
385 } else {
386 std::string error;
387 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
388 EXPECT_PRED_FORMAT2(
389 AssertStartsWith, error,
390 "Failed to set local pranswer sdp: Called in wrong state:");
391 }
392 }
393
TEST_P(PeerConnectionSignalingStateTest,SetLocalAnswer)394 TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
395 auto wrapper_for_answer =
396 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
397 auto answer = wrapper_for_answer->CreateAnswer();
398
399 auto wrapper = CreatePeerConnectionUnderTest();
400 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
401 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
402 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
403 } else {
404 std::string error;
405 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
406 EXPECT_PRED_FORMAT2(
407 AssertStartsWith, error,
408 "Failed to set local answer sdp: Called in wrong state:");
409 }
410 }
411
TEST_P(PeerConnectionSignalingStateTest,SetRemoteOffer)412 TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
413 auto wrapper_for_offer =
414 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
415 auto offer =
416 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
417
418 auto wrapper = CreatePeerConnectionUnderTest();
419 if (wrapper->signaling_state() == SignalingState::kStable ||
420 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
421 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
422 } else {
423 std::string error;
424 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
425 EXPECT_PRED_FORMAT2(
426 AssertStartsWith, error,
427 "Failed to set remote offer sdp: Called in wrong state:");
428 }
429 }
430
TEST_P(PeerConnectionSignalingStateTest,SetRemotePrAnswer)431 TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
432 auto wrapper_for_pranswer =
433 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
434 auto pranswer =
435 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
436
437 auto wrapper = CreatePeerConnectionUnderTest();
438 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
439 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
440 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
441 } else {
442 std::string error;
443 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
444 EXPECT_PRED_FORMAT2(
445 AssertStartsWith, error,
446 "Failed to set remote pranswer sdp: Called in wrong state:");
447 }
448 }
449
TEST_P(PeerConnectionSignalingStateTest,SetRemoteAnswer)450 TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
451 auto wrapper_for_answer =
452 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
453 auto answer = wrapper_for_answer->CreateAnswer();
454
455 auto wrapper = CreatePeerConnectionUnderTest();
456 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
457 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
458 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
459 } else {
460 std::string error;
461 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
462 EXPECT_PRED_FORMAT2(
463 AssertStartsWith, error,
464 "Failed to set remote answer sdp: Called in wrong state:");
465 }
466 }
467
468 INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
469 PeerConnectionSignalingStateTest,
470 Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
471 SdpSemantics::kUnifiedPlan),
472 Values(SignalingState::kStable,
473 SignalingState::kHaveLocalOffer,
474 SignalingState::kHaveLocalPrAnswer,
475 SignalingState::kHaveRemoteOffer,
476 SignalingState::kHaveRemotePrAnswer),
477 Bool()));
478
479 // Test that CreateAnswer fails if a round of offer/answer has been done and
480 // the PeerConnection is in the stable state.
TEST_P(PeerConnectionSignalingTest,CreateAnswerFailsIfStable)481 TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
482 auto caller = CreatePeerConnection();
483 auto callee = CreatePeerConnection();
484
485 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
486
487 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
488 EXPECT_FALSE(caller->CreateAnswer());
489
490 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
491 EXPECT_FALSE(callee->CreateAnswer());
492 }
493
494 // According to https://tools.ietf.org/html/rfc3264#section-8, the session id
495 // stays the same but the version must be incremented if a later, different
496 // session description is generated. These two tests verify that is the case for
497 // both offers and answers.
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentOffer)498 TEST_P(PeerConnectionSignalingTest,
499 SessionVersionIncrementedInSubsequentDifferentOffer) {
500 auto caller = CreatePeerConnection();
501 auto callee = CreatePeerConnection();
502
503 auto original_offer = caller->CreateOfferAndSetAsLocal();
504 const std::string original_id = original_offer->session_id();
505 const std::string original_version = original_offer->session_version();
506
507 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
508 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
509
510 // Add track to get a different offer.
511 caller->AddAudioTrack("a");
512
513 auto later_offer = caller->CreateOffer();
514
515 EXPECT_EQ(original_id, later_offer->session_id());
516 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
517 rtc::FromString<uint64_t>(later_offer->session_version()));
518 }
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentAnswer)519 TEST_P(PeerConnectionSignalingTest,
520 SessionVersionIncrementedInSubsequentDifferentAnswer) {
521 auto caller = CreatePeerConnection();
522 auto callee = CreatePeerConnection();
523
524 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
525
526 auto original_answer = callee->CreateAnswer();
527 const std::string original_id = original_answer->session_id();
528 const std::string original_version = original_answer->session_version();
529
530 // Add track to get a different answer.
531 callee->AddAudioTrack("a");
532
533 auto later_answer = callee->CreateAnswer();
534
535 EXPECT_EQ(original_id, later_answer->session_id());
536 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
537 rtc::FromString<uint64_t>(later_answer->session_version()));
538 }
539
TEST_P(PeerConnectionSignalingTest,InitiatorFlagSetOnCallerAndNotOnCallee)540 TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
541 auto caller = CreatePeerConnectionWithAudioVideo();
542 auto callee = CreatePeerConnectionWithAudioVideo();
543
544 EXPECT_FALSE(caller->initial_offerer());
545 EXPECT_FALSE(callee->initial_offerer());
546
547 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
548
549 EXPECT_TRUE(caller->initial_offerer());
550 EXPECT_FALSE(callee->initial_offerer());
551
552 ASSERT_TRUE(
553 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
554
555 EXPECT_TRUE(caller->initial_offerer());
556 EXPECT_FALSE(callee->initial_offerer());
557 }
558
559 // Test creating a PeerConnection, request multiple offers, destroy the
560 // PeerConnection and make sure we get success/failure callbacks for all of the
561 // requests.
562 // Background: crbug.com/507307
TEST_P(PeerConnectionSignalingTest,CreateOffersAndShutdown)563 TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
564 auto caller = CreatePeerConnection();
565
566 RTCOfferAnswerOptions options;
567 options.offer_to_receive_audio =
568 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
569
570 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
571 for (auto& observer : observers) {
572 observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
573 caller->pc()->CreateOffer(observer.get(), options);
574 }
575
576 // Destroy the PeerConnection.
577 caller.reset(nullptr);
578
579 for (auto& observer : observers) {
580 // We expect to have received a notification now even if the PeerConnection
581 // was terminated. The offer creation may or may not have succeeded, but we
582 // must have received a notification.
583 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
584 }
585 }
586
587 // Similar to the above test, but by closing the PC first the CreateOffer() will
588 // fail "early", which triggers a codepath where the PeerConnection is
589 // reponsible for invoking the observer, instead of the normal codepath where
590 // the WebRtcSessionDescriptionFactory is responsible for it.
TEST_P(PeerConnectionSignalingTest,CloseCreateOfferAndShutdown)591 TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
592 auto caller = CreatePeerConnection();
593 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
594 caller->pc()->Close();
595 caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
596 caller.reset(nullptr);
597 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
598 }
599
TEST_P(PeerConnectionSignalingTest,ImplicitCreateOfferAndShutdownWithOldObserver)600 TEST_P(PeerConnectionSignalingTest,
601 ImplicitCreateOfferAndShutdownWithOldObserver) {
602 auto caller = CreatePeerConnection();
603 auto observer = MockSetSessionDescriptionObserver::Create();
604 caller->pc()->SetLocalDescription(observer.get());
605 caller.reset(nullptr);
606 // The old observer does not get invoked because posted messages are lost.
607 EXPECT_FALSE(observer->called());
608 }
609
TEST_P(PeerConnectionSignalingTest,ImplicitCreateOfferAndShutdown)610 TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
611 auto caller = CreatePeerConnection();
612 auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
613 caller->pc()->SetLocalDescription(observer);
614 caller.reset(nullptr);
615 // The new observer gets invoked because it is called immediately.
616 EXPECT_TRUE(observer->called());
617 EXPECT_FALSE(observer->error().ok());
618 }
619
TEST_P(PeerConnectionSignalingTest,CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver)620 TEST_P(PeerConnectionSignalingTest,
621 CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
622 auto caller = CreatePeerConnection();
623 auto observer = MockSetSessionDescriptionObserver::Create();
624 caller->pc()->Close();
625 caller->pc()->SetLocalDescription(observer.get());
626 caller.reset(nullptr);
627 // The old observer does not get invoked because posted messages are lost.
628 EXPECT_FALSE(observer->called());
629 }
630
TEST_P(PeerConnectionSignalingTest,CloseBeforeImplicitCreateOfferAndShutdown)631 TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
632 auto caller = CreatePeerConnection();
633 auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
634 caller->pc()->Close();
635 caller->pc()->SetLocalDescription(observer);
636 caller.reset(nullptr);
637 // The new observer gets invoked because it is called immediately.
638 EXPECT_TRUE(observer->called());
639 EXPECT_FALSE(observer->error().ok());
640 }
641
TEST_P(PeerConnectionSignalingTest,CloseAfterImplicitCreateOfferAndShutdownWithOldObserver)642 TEST_P(PeerConnectionSignalingTest,
643 CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
644 auto caller = CreatePeerConnection();
645 auto observer = MockSetSessionDescriptionObserver::Create();
646 caller->pc()->SetLocalDescription(observer.get());
647 caller->pc()->Close();
648 caller.reset(nullptr);
649 // The old observer does not get invoked because posted messages are lost.
650 EXPECT_FALSE(observer->called());
651 }
652
TEST_P(PeerConnectionSignalingTest,CloseAfterImplicitCreateOfferAndShutdown)653 TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
654 auto caller = CreatePeerConnection();
655 auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
656 caller->pc()->SetLocalDescription(observer);
657 caller->pc()->Close();
658 caller.reset(nullptr);
659 // The new observer gets invoked because it is called immediately.
660 EXPECT_TRUE(observer->called());
661 EXPECT_FALSE(observer->error().ok());
662 }
663
TEST_P(PeerConnectionSignalingTest,SetLocalDescriptionNewObserverIsInvokedImmediately)664 TEST_P(PeerConnectionSignalingTest,
665 SetLocalDescriptionNewObserverIsInvokedImmediately) {
666 auto caller = CreatePeerConnection();
667 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
668
669 auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
670 caller->pc()->SetLocalDescription(std::move(offer), observer);
671 // The new observer is invoked immediately.
672 EXPECT_TRUE(observer->called());
673 EXPECT_TRUE(observer->error().ok());
674 }
675
TEST_P(PeerConnectionSignalingTest,SetLocalDescriptionOldObserverIsInvokedInAPostedMessage)676 TEST_P(PeerConnectionSignalingTest,
677 SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
678 auto caller = CreatePeerConnection();
679 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
680
681 auto observer = MockSetSessionDescriptionObserver::Create();
682 caller->pc()->SetLocalDescription(observer.get(), offer.release());
683 // The old observer is not invoked immediately.
684 EXPECT_FALSE(observer->called());
685 // Process all currently pending messages by waiting for a posted task to run.
686 bool checkpoint_reached = false;
687 rtc::Thread::Current()->PostTask(
688 [&checkpoint_reached] { checkpoint_reached = true; });
689 EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
690 // If resolving the observer was pending, it must now have been called.
691 EXPECT_TRUE(observer->called());
692 }
693
TEST_P(PeerConnectionSignalingTest,SetRemoteDescriptionExecutesImmediately)694 TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
695 auto caller = CreatePeerConnectionWithAudioVideo();
696 auto callee = CreatePeerConnection();
697
698 // This offer will cause receivers to be created.
699 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
700
701 // By not waiting for the observer's callback we can verify that the operation
702 // executed immediately.
703 callee->pc()->SetRemoteDescription(
704 std::move(offer),
705 rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
706 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
707 }
708
TEST_P(PeerConnectionSignalingTest,CreateOfferBlocksSetRemoteDescription)709 TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
710 auto caller = CreatePeerConnectionWithAudioVideo();
711 auto callee = CreatePeerConnection();
712
713 // This offer will cause receivers to be created.
714 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
715
716 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
717 auto offer_observer =
718 rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
719 // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
720 // SetRemoteDescription() operation should be chained to be executed
721 // asynchronously, when CreateOffer() completes.
722 callee->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
723 callee->pc()->SetRemoteDescription(
724 std::move(offer),
725 rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
726 // CreateOffer() is asynchronous; without message processing this operation
727 // should not have completed.
728 EXPECT_FALSE(offer_observer->called());
729 // Due to chaining, the receivers should not have been created by the offer
730 // yet.
731 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
732 // EXPECT_TRUE_WAIT causes messages to be processed...
733 EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
734 // Now that the offer has been completed, SetRemoteDescription() will have
735 // been executed next in the chain.
736 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
737 }
738
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesOffer)739 TEST_P(PeerConnectionSignalingTest,
740 ParameterlessSetLocalDescriptionCreatesOffer) {
741 auto caller = CreatePeerConnectionWithAudioVideo();
742
743 auto observer = MockSetSessionDescriptionObserver::Create();
744 caller->pc()->SetLocalDescription(observer.get());
745
746 // The offer is created asynchronously; message processing is needed for it to
747 // complete.
748 EXPECT_FALSE(observer->called());
749 EXPECT_FALSE(caller->pc()->pending_local_description());
750 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
751
752 // Wait for messages to be processed.
753 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
754 EXPECT_TRUE(observer->result());
755 EXPECT_TRUE(caller->pc()->pending_local_description());
756 EXPECT_EQ(SdpType::kOffer,
757 caller->pc()->pending_local_description()->GetType());
758 EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
759 }
760
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesAnswer)761 TEST_P(PeerConnectionSignalingTest,
762 ParameterlessSetLocalDescriptionCreatesAnswer) {
763 auto caller = CreatePeerConnectionWithAudioVideo();
764 auto callee = CreatePeerConnectionWithAudioVideo();
765
766 callee->SetRemoteDescription(caller->CreateOffer());
767 EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
768
769 auto observer = MockSetSessionDescriptionObserver::Create();
770 callee->pc()->SetLocalDescription(observer.get());
771
772 // The answer is created asynchronously; message processing is needed for it
773 // to complete.
774 EXPECT_FALSE(observer->called());
775 EXPECT_FALSE(callee->pc()->current_local_description());
776
777 // Wait for messages to be processed.
778 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
779 EXPECT_TRUE(observer->result());
780 EXPECT_TRUE(callee->pc()->current_local_description());
781 EXPECT_EQ(SdpType::kAnswer,
782 callee->pc()->current_local_description()->GetType());
783 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
784 }
785
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionFullExchange)786 TEST_P(PeerConnectionSignalingTest,
787 ParameterlessSetLocalDescriptionFullExchange) {
788 auto caller = CreatePeerConnectionWithAudioVideo();
789 auto callee = CreatePeerConnectionWithAudioVideo();
790
791 // SetLocalDescription(), implicitly creating an offer.
792 auto caller_set_local_description_observer =
793 MockSetSessionDescriptionObserver::Create();
794 caller->pc()->SetLocalDescription(
795 caller_set_local_description_observer.get());
796 EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
797 kWaitTimeout);
798 ASSERT_TRUE(caller->pc()->pending_local_description());
799
800 // SetRemoteDescription(offer)
801 auto callee_set_remote_description_observer =
802 MockSetSessionDescriptionObserver::Create();
803 callee->pc()->SetRemoteDescription(
804 callee_set_remote_description_observer.get(),
805 CloneSessionDescription(caller->pc()->pending_local_description())
806 .release());
807
808 // SetLocalDescription(), implicitly creating an answer.
809 auto callee_set_local_description_observer =
810 MockSetSessionDescriptionObserver::Create();
811 callee->pc()->SetLocalDescription(
812 callee_set_local_description_observer.get());
813 EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
814 kWaitTimeout);
815 // Chaining guarantees SetRemoteDescription() happened before
816 // SetLocalDescription().
817 EXPECT_TRUE(callee_set_remote_description_observer->called());
818 EXPECT_TRUE(callee->pc()->current_local_description());
819
820 // SetRemoteDescription(answer)
821 auto caller_set_remote_description_observer =
822 MockSetSessionDescriptionObserver::Create();
823 caller->pc()->SetRemoteDescription(
824 caller_set_remote_description_observer.get(),
825 CloneSessionDescription(callee->pc()->current_local_description())
826 .release());
827 EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
828 kWaitTimeout);
829
830 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
831 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
832 }
833
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer)834 TEST_P(PeerConnectionSignalingTest,
835 ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
836 auto caller = CreatePeerConnectionWithAudioVideo();
837
838 auto observer = MockSetSessionDescriptionObserver::Create();
839 caller->pc()->Close();
840 caller->pc()->SetLocalDescription(observer.get());
841
842 // The operation should fail asynchronously.
843 EXPECT_FALSE(observer->called());
844 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
845 EXPECT_FALSE(observer->result());
846 // This did not affect the signaling state.
847 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
848 EXPECT_EQ(
849 "SetLocalDescription failed to create session description - "
850 "SetLocalDescription called when PeerConnection is closed.",
851 observer->error());
852 }
853
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseWhileCreatingOffer)854 TEST_P(PeerConnectionSignalingTest,
855 ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
856 auto caller = CreatePeerConnectionWithAudioVideo();
857
858 auto observer = MockSetSessionDescriptionObserver::Create();
859 caller->pc()->SetLocalDescription(observer.get());
860 caller->pc()->Close();
861
862 // The operation should fail asynchronously.
863 EXPECT_FALSE(observer->called());
864 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
865 EXPECT_FALSE(observer->result());
866 // This did not affect the signaling state.
867 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
868 EXPECT_EQ(
869 "SetLocalDescription failed to create session description - "
870 "CreateOffer failed because the session was shut down",
871 observer->error());
872 }
873
TEST_P(PeerConnectionSignalingTest,UnsupportedContentType)874 TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
875 auto caller = CreatePeerConnection();
876
877 // Call setRemoteDescription with a m= line we don't understand.
878 std::string sdp =
879 "v=0\r\n"
880 "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
881 "s=-\r\n"
882 "t=0 0\r\n"
883 "m=bogus 9 FOO 0 8\r\n"
884 "c=IN IP4 0.0.0.0\r\n"
885 "a=mid:bogusmid\r\n";
886 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
887 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
888
889 EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
890
891 // Assert we respond back with something meaningful.
892 auto answer = caller->CreateAnswer();
893 ASSERT_EQ(answer->description()->contents().size(), 1u);
894 EXPECT_NE(answer->description()
895 ->contents()[0]
896 .media_description()
897 ->as_unsupported(),
898 nullptr);
899 EXPECT_EQ(answer->description()
900 ->contents()[0]
901 .media_description()
902 ->as_unsupported()
903 ->media_type(),
904 "bogus");
905 EXPECT_TRUE(answer->description()->contents()[0].rejected);
906 EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
907 EXPECT_EQ(
908 answer->description()->contents()[0].media_description()->protocol(),
909 "FOO");
910 EXPECT_FALSE(
911 answer->description()->contents()[0].media_description()->has_codecs());
912
913 EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
914
915 // Assert we keep this in susequent offers.
916 auto offer = caller->CreateOffer();
917 EXPECT_EQ(offer->description()
918 ->contents()[0]
919 .media_description()
920 ->as_unsupported()
921 ->media_type(),
922 "bogus");
923 EXPECT_TRUE(offer->description()->contents()[0].rejected);
924 EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
925 "FOO");
926 EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
927 EXPECT_FALSE(
928 offer->description()->contents()[0].media_description()->has_codecs());
929 EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
930 }
931
TEST_P(PeerConnectionSignalingTest,ReceiveFlexFec)932 TEST_P(PeerConnectionSignalingTest, ReceiveFlexFec) {
933 auto caller = CreatePeerConnection();
934
935 std::string sdp =
936 "v=0\r\n"
937 "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
938 "s=-\r\n"
939 "t=0 0\r\n"
940 "a=group:BUNDLE 0\r\n"
941 "m=video 9 UDP/TLS/RTP/SAVPF 102 122\r\n"
942 "c=IN IP4 0.0.0.0\r\n"
943 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
944 "a=ice-ufrag:IZeV\r\n"
945 "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
946 "a=ice-options:trickle\r\n"
947 "a=fingerprint:sha-256 "
948 "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
949 "1C:2C:74:01:8D:50:67:23\r\n"
950 "a=setup:actpass\r\n"
951 "a=mid:0\r\n"
952 "a=sendrecv\r\n"
953 "a=msid:stream track\r\n"
954 "a=rtcp-mux\r\n"
955 "a=rtcp-rsize\r\n"
956 "a=rtpmap:102 VP8/90000\r\n"
957 "a=rtcp-fb:102 goog-remb\r\n"
958 "a=rtcp-fb:102 transport-cc\r\n"
959 "a=rtcp-fb:102 ccm fir\r\n"
960 "a=rtcp-fb:102 nack\r\n"
961 "a=rtcp-fb:102 nack pli\r\n"
962 "a=rtpmap:122 flexfec-03/90000\r\n"
963 "a=fmtp:122 repair-window=10000000\r\n"
964 "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
965 "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
966 "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
967 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
968 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
969
970 EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
971
972 auto answer = caller->CreateAnswer();
973 ASSERT_EQ(answer->description()->contents().size(), 1u);
974 ASSERT_NE(
975 answer->description()->contents()[0].media_description()->as_video(),
976 nullptr);
977 auto codecs = answer->description()
978 ->contents()[0]
979 .media_description()
980 ->as_video()
981 ->codecs();
982 ASSERT_EQ(codecs.size(), 2u);
983 EXPECT_EQ(codecs[1].name, "flexfec-03");
984
985 EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
986 }
987
TEST_P(PeerConnectionSignalingTest,ReceiveFlexFecReoffer)988 TEST_P(PeerConnectionSignalingTest, ReceiveFlexFecReoffer) {
989 auto caller = CreatePeerConnection();
990
991 std::string sdp =
992 "v=0\r\n"
993 "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
994 "s=-\r\n"
995 "t=0 0\r\n"
996 "a=group:BUNDLE 0\r\n"
997 "m=video 9 UDP/TLS/RTP/SAVPF 102 35\r\n"
998 "c=IN IP4 0.0.0.0\r\n"
999 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1000 "a=ice-ufrag:IZeV\r\n"
1001 "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1002 "a=ice-options:trickle\r\n"
1003 "a=fingerprint:sha-256 "
1004 "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1005 "1C:2C:74:01:8D:50:67:23\r\n"
1006 "a=setup:actpass\r\n"
1007 "a=mid:0\r\n"
1008 "a=sendrecv\r\n"
1009 "a=msid:stream track\r\n"
1010 "a=rtcp-mux\r\n"
1011 "a=rtcp-rsize\r\n"
1012 "a=rtpmap:102 VP8/90000\r\n"
1013 "a=rtcp-fb:102 goog-remb\r\n"
1014 "a=rtcp-fb:102 transport-cc\r\n"
1015 "a=rtcp-fb:102 ccm fir\r\n"
1016 "a=rtcp-fb:102 nack\r\n"
1017 "a=rtcp-fb:102 nack pli\r\n"
1018 "a=rtpmap:35 flexfec-03/90000\r\n"
1019 "a=fmtp:35 repair-window=10000000\r\n"
1020 "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
1021 "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
1022 "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
1023 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1024 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1025
1026 EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
1027
1028 auto answer = caller->CreateAnswer();
1029 ASSERT_EQ(answer->description()->contents().size(), 1u);
1030 ASSERT_NE(
1031 answer->description()->contents()[0].media_description()->as_video(),
1032 nullptr);
1033 auto codecs = answer->description()
1034 ->contents()[0]
1035 .media_description()
1036 ->as_video()
1037 ->codecs();
1038 ASSERT_EQ(codecs.size(), 2u);
1039 EXPECT_EQ(codecs[1].name, "flexfec-03");
1040 EXPECT_EQ(codecs[1].id, 35);
1041
1042 EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
1043
1044 // This generates a collision for AV1 which needs to be remapped.
1045 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1046 auto offer_codecs = offer->description()
1047 ->contents()[0]
1048 .media_description()
1049 ->as_video()
1050 ->codecs();
1051 auto flexfec_it = std::find_if(
1052 offer_codecs.begin(), offer_codecs.end(),
1053 [](const cricket::Codec& codec) { return codec.name == "flexfec-03"; });
1054 ASSERT_EQ(flexfec_it->id, 35);
1055 auto av1_it = std::find_if(
1056 offer_codecs.begin(), offer_codecs.end(),
1057 [](const cricket::Codec& codec) { return codec.name == "AV1"; });
1058 if (av1_it != offer_codecs.end()) {
1059 ASSERT_NE(av1_it->id, 35);
1060 }
1061 }
1062
TEST_P(PeerConnectionSignalingTest,MidAttributeMaxLength)1063 TEST_P(PeerConnectionSignalingTest, MidAttributeMaxLength) {
1064 auto caller = CreatePeerConnection();
1065
1066 std::string sdp =
1067 "v=0\r\n"
1068 "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
1069 "s=-\r\n"
1070 "t=0 0\r\n"
1071 "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
1072 "c=IN IP4 0.0.0.0\r\n"
1073 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1074 "a=ice-ufrag:IZeV\r\n"
1075 "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1076 "a=ice-options:trickle\r\n"
1077 "a=fingerprint:sha-256 "
1078 "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1079 "1C:2C:74:01:8D:50:67:23\r\n"
1080 "a=setup:actpass\r\n"
1081 // Too long mid attribute.
1082 "a=mid:0123456789012345678901234567890123\r\n"
1083 "a=sendrecv\r\n"
1084 "a=msid:stream track\r\n"
1085 "a=rtcp-mux\r\n"
1086 "a=rtcp-rsize\r\n"
1087 "a=rtpmap:102 VP8/90000\r\n"
1088 "a=rtcp-fb:102 goog-remb\r\n"
1089 "a=rtcp-fb:102 transport-cc\r\n"
1090 "a=rtcp-fb:102 ccm fir\r\n"
1091 "a=rtcp-fb:102 nack\r\n"
1092 "a=rtcp-fb:102 nack pli\r\n"
1093 "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
1094 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1095 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1096
1097 EXPECT_FALSE(caller->SetRemoteDescription(std::move(remote_description)));
1098 }
1099
1100 INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
1101 PeerConnectionSignalingTest,
1102 Values(SdpSemantics::kPlanB_DEPRECATED,
1103 SdpSemantics::kUnifiedPlan));
1104
1105 class PeerConnectionSignalingUnifiedPlanTest
1106 : public PeerConnectionSignalingBaseTest {
1107 protected:
PeerConnectionSignalingUnifiedPlanTest()1108 PeerConnectionSignalingUnifiedPlanTest()
1109 : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
1110 };
1111
1112 // We verify that SetLocalDescription() executed immediately by verifying that
1113 // the transceiver mid values got assigned. SLD executing immeditately is not
1114 // unique to Unified Plan, but the transceivers used to verify this are only
1115 // available in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyUsingOldObserver)1116 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1117 SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
1118 auto caller = CreatePeerConnectionWithAudioVideo();
1119
1120 // This offer will cause transceiver mids to get assigned.
1121 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1122
1123 // By not waiting for the observer's callback we can verify that the operation
1124 // executed immediately. The old observer is invoked in a posted message, so
1125 // waiting for it would not ensure synchronicity.
1126 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
1127 caller->pc()->SetLocalDescription(
1128 rtc::make_ref_counted<MockSetSessionDescriptionObserver>().get(),
1129 offer.release());
1130 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
1131 }
1132
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyUsingNewObserver)1133 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1134 SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
1135 auto caller = CreatePeerConnectionWithAudioVideo();
1136
1137 // This offer will cause transceiver mids to get assigned.
1138 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1139
1140 // Verify that mids were assigned without waiting for the observer. (However,
1141 // the new observer should also be invoked synchronously - as is ensured by
1142 // other tests.)
1143 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
1144 caller->pc()->SetLocalDescription(
1145 std::move(offer),
1146 rtc::make_ref_counted<FakeSetLocalDescriptionObserver>());
1147 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
1148 }
1149
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback)1150 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1151 SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
1152 auto caller = CreatePeerConnectionWithAudioVideo();
1153
1154 // This offer will cause transceiver mids to get assigned.
1155 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1156
1157 auto offer_observer =
1158 rtc::make_ref_counted<ExecuteFunctionOnCreateSessionDescriptionObserver>(
1159 [pc = caller->pc()](SessionDescriptionInterface* desc) {
1160 // By not waiting for the observer's callback we can verify that the
1161 // operation executed immediately.
1162 RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
1163 pc->SetLocalDescription(
1164 rtc::make_ref_counted<MockSetSessionDescriptionObserver>()
1165 .get(),
1166 desc);
1167 EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
1168 });
1169 caller->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
1170 EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
1171 }
1172
1173 // Test that transports are shown in the sender/receiver API after offer/answer.
1174 // This only works in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsInstantiateInOfferAnswer)1175 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1176 DtlsTransportsInstantiateInOfferAnswer) {
1177 auto caller = CreatePeerConnectionWithAudioVideo();
1178 auto callee = CreatePeerConnection();
1179
1180 EXPECT_FALSE(HasDtlsTransport(caller));
1181 EXPECT_FALSE(HasDtlsTransport(callee));
1182 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1183 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1184 EXPECT_TRUE(HasDtlsTransport(caller));
1185 callee->SetRemoteDescription(std::move(offer));
1186 EXPECT_FALSE(HasDtlsTransport(callee));
1187 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1188 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1189 EXPECT_TRUE(HasDtlsTransport(callee));
1190 caller->SetRemoteDescription(std::move(answer));
1191 EXPECT_TRUE(HasDtlsTransport(caller));
1192
1193 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1194 }
1195
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsMergeWhenBundled)1196 TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
1197 auto caller = CreatePeerConnectionWithAudioVideo();
1198 auto callee = CreatePeerConnection();
1199
1200 EXPECT_FALSE(HasDtlsTransport(caller));
1201 EXPECT_FALSE(HasDtlsTransport(callee));
1202 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1203 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1204 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1205 callee->SetRemoteDescription(std::move(offer));
1206 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1207 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1208 caller->SetRemoteDescription(std::move(answer));
1209 EXPECT_EQ(1, NumberOfDtlsTransports(caller));
1210
1211 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1212 }
1213
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsAreSeparateeWhenUnbundled)1214 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1215 DtlsTransportsAreSeparateeWhenUnbundled) {
1216 auto caller = CreatePeerConnectionWithAudioVideo();
1217 auto callee = CreatePeerConnection();
1218
1219 EXPECT_FALSE(HasDtlsTransport(caller));
1220 EXPECT_FALSE(HasDtlsTransport(callee));
1221 RTCOfferAnswerOptions unbundle_options;
1222 unbundle_options.use_rtp_mux = false;
1223 auto offer = caller->CreateOffer(unbundle_options);
1224 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1225 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1226 callee->SetRemoteDescription(std::move(offer));
1227 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1228 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1229 EXPECT_EQ(2, NumberOfDtlsTransports(callee));
1230 caller->SetRemoteDescription(std::move(answer));
1231 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1232
1233 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1234 }
1235
TEST_F(PeerConnectionSignalingUnifiedPlanTest,ShouldFireNegotiationNeededWhenNoChangesArePending)1236 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1237 ShouldFireNegotiationNeededWhenNoChangesArePending) {
1238 auto caller = CreatePeerConnection();
1239 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1240 auto transceiver =
1241 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1242 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1243 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1244 caller->observer()->latest_negotiation_needed_event()));
1245 }
1246
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SuppressNegotiationNeededWhenOperationChainIsNotEmpty)1247 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1248 SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
1249 auto caller = CreatePeerConnection();
1250 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1251 auto transceiver =
1252 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1253 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1254
1255 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
1256 caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
1257 // For this test to work, the operation has to be pending, i.e. the observer
1258 // has not yet been invoked.
1259 EXPECT_FALSE(observer->called());
1260 // Because the Operations Chain is not empty, the event is now suppressed.
1261 EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
1262 caller->observer()->latest_negotiation_needed_event()));
1263 caller->observer()->clear_latest_negotiation_needed_event();
1264
1265 // When the Operations Chain becomes empty again, a new negotiation needed
1266 // event will be generated that is not suppressed.
1267 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
1268 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1269 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1270 caller->observer()->latest_negotiation_needed_event()));
1271 }
1272
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SuppressNegotiationNeededWhenSignalingStateIsNotStable)1273 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1274 SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
1275 auto caller = CreatePeerConnection();
1276 auto callee = CreatePeerConnection();
1277 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1278
1279 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1280 auto transceiver =
1281 callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1282 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1283
1284 // Change signaling state (to "have-remote-offer") by setting a remote offer.
1285 callee->SetRemoteDescription(std::move(offer));
1286 // Because the signaling state is not "stable", the event is now suppressed.
1287 EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
1288 callee->observer()->latest_negotiation_needed_event()));
1289 callee->observer()->clear_latest_negotiation_needed_event();
1290
1291 // Upon rolling back to "stable", a new negotiation needed event will be
1292 // generated that is not suppressed.
1293 callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
1294 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1295 EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
1296 callee->observer()->latest_negotiation_needed_event()));
1297 }
1298
TEST_F(PeerConnectionSignalingUnifiedPlanTest,RtxReofferApt)1299 TEST_F(PeerConnectionSignalingUnifiedPlanTest, RtxReofferApt) {
1300 auto callee = CreatePeerConnection();
1301
1302 std::string sdp =
1303 "v=0\r\n"
1304 "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
1305 "s=-\r\n"
1306 "t=0 0\r\n"
1307 "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
1308 "c=IN IP4 0.0.0.0\r\n"
1309 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1310 "a=ice-ufrag:IZeV\r\n"
1311 "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1312 "a=ice-options:trickle\r\n"
1313 "a=fingerprint:sha-256 "
1314 "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1315 "1C:2C:74:01:8D:50:67:23\r\n"
1316 "a=setup:actpass\r\n"
1317 "a=mid:0\r\n"
1318 "a=sendrecv\r\n"
1319 "a=msid:stream track\r\n"
1320 "a=rtcp-mux\r\n"
1321 "a=rtcp-rsize\r\n"
1322 "a=rtpmap:102 VP8/90000\r\n"
1323 "a=rtcp-fb:102 goog-remb\r\n"
1324 "a=rtcp-fb:102 transport-cc\r\n"
1325 "a=rtcp-fb:102 ccm fir\r\n"
1326 "a=rtcp-fb:102 nack\r\n"
1327 "a=rtcp-fb:102 nack pli\r\n"
1328 "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
1329 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1330 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1331
1332 EXPECT_TRUE(callee->SetRemoteDescription(std::move(remote_description)));
1333
1334 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1335 EXPECT_TRUE(
1336 callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1337
1338 callee->pc()->GetTransceivers()[0]->StopStandard();
1339 auto reoffer = callee->CreateOffer(RTCOfferAnswerOptions());
1340 auto codecs = reoffer->description()
1341 ->contents()[0]
1342 .media_description()
1343 ->as_video()
1344 ->codecs();
1345 ASSERT_GT(codecs.size(), 2u);
1346 EXPECT_EQ(codecs[0].name, "VP8");
1347 EXPECT_EQ(codecs[1].name, "rtx");
1348 auto apt_it = codecs[1].params.find("apt");
1349 ASSERT_NE(apt_it, codecs[1].params.end());
1350 // The apt should match the id from the remote offer.
1351 EXPECT_EQ(apt_it->second, rtc::ToString(codecs[0].id));
1352 EXPECT_EQ(apt_it->second, "102");
1353 }
1354
1355 } // namespace webrtc
1356