diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 429c4debea..fd9477274f 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -2440,6 +2440,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:network", "../rtc_base:network_constants", "../rtc_base:null_socket_server", + "../rtc_base:random", "../rtc_base:refcount", "../rtc_base:rtc_base_tests_utils", "../rtc_base:rtc_certificate_generator", diff --git a/pc/data_channel_integrationtest.cc b/pc/data_channel_integrationtest.cc index 4489618306..1a23a1720b 100644 --- a/pc/data_channel_integrationtest.cc +++ b/pc/data_channel_integrationtest.cc @@ -111,8 +111,8 @@ class DataChannelIntegrationTestUnifiedPlan : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {} }; -void MakeActiveSctpOffer(cricket::SessionDescription* desc) { - auto& transport_infos = desc->transport_infos(); +void MakeActiveSctpOffer(std::unique_ptr& desc) { + auto& transport_infos = desc->description()->transport_infos(); for (auto& transport_info : transport_infos) { transport_info.description.connection_role = cricket::CONNECTIONROLE_ACTIVE; } @@ -770,9 +770,10 @@ TEST_P(DataChannelIntegrationTest, SctpDataChannelToAudioVideoUpgrade) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } -static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) { +static void MakeSpecCompliantSctpOffer( + std::unique_ptr& desc) { cricket::SctpDataContentDescription* dcd_offer = - GetFirstSctpDataContentDescription(desc); + GetFirstSctpDataContentDescription(desc->description()); // See https://crbug.com/webrtc/11211 - this function is a no-op ASSERT_TRUE(dcd_offer); dcd_offer->set_use_sctpmap(false); @@ -913,10 +914,11 @@ TEST_P(DataChannelIntegrationTest, ConnectFakeSignaling(); caller()->CreateDataChannel(); - callee()->SetReceivedSdpMunger([this](cricket::SessionDescription* desc) { - MakeActiveSctpOffer(desc); - callee()->CreateDataChannel(); - }); + callee()->SetReceivedSdpMunger( + [this](std::unique_ptr& desc) { + MakeActiveSctpOffer(desc); + callee()->CreateDataChannel(); + }); caller()->CreateAndSetAndSignalOffer(); ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index 8362c8bfde..7bf6b6d954 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -84,6 +84,7 @@ #include "rtc_base/firewall_socket_server.h" #include "rtc_base/gunit.h" #include "rtc_base/logging.h" +#include "rtc_base/random.h" #include "rtc_base/socket_address.h" #include "rtc_base/ssl_certificate.h" #include "rtc_base/ssl_fingerprint.h" @@ -605,9 +606,10 @@ TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) { caller()->AddAudioVideoTracks(); callee()->AddAudioVideoTracks(); // Remove the bundle group from the SDP received by the callee. - callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) { - desc->RemoveGroupByName("BUNDLE"); - }); + callee()->SetReceivedSdpMunger( + [](std::unique_ptr& sdp) { + sdp->description()->RemoveGroupByName("BUNDLE"); + }); caller()->CreateAndSetAndSignalOffer(); ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); { @@ -673,11 +675,12 @@ TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) { callee()->CreateLocalVideoTrackWithRotation(kVideoRotation_270)); // Remove the CVO extension from the offered SDP. - callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) { - cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(desc); - video->ClearRtpHeaderExtensions(); - }); + callee()->SetReceivedSdpMunger( + [](std::unique_ptr& sdp) { + cricket::VideoContentDescription* video = + GetFirstVideoContentDescription(sdp->description()); + video->ClearRtpHeaderExtensions(); + }); // Wait for video frames to be received by both sides. caller()->CreateAndSetAndSignalOffer(); ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); @@ -845,8 +848,8 @@ TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) { // Renegotiate, rejecting the video m= section. if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) { caller()->SetGeneratedSdpMunger( - [](cricket::SessionDescription* description) { - for (cricket::ContentInfo& content : description->contents()) { + [](std::unique_ptr& sdp) { + for (cricket::ContentInfo& content : sdp->description()->contents()) { if (cricket::IsVideoContent(&content)) { content.rejected = true; } @@ -1010,10 +1013,11 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, } // Used for the test below. -void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) { - RemoveSsrcsAndKeepMsids(desc); - desc->RemoveGroupByName("BUNDLE"); - for (ContentInfo& content : desc->contents()) { +void RemoveBundleGroupSsrcsAndMidExtension( + std::unique_ptr& sdp) { + RemoveSsrcsAndKeepMsids(sdp); + sdp->description()->RemoveGroupByName("BUNDLE"); + for (ContentInfo& content : sdp->description()->contents()) { cricket::MediaContentDescription* media = content.media_description(); cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions(); extensions.erase(std::remove_if(extensions.begin(), extensions.end(), @@ -1058,9 +1062,9 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, // Used for the test below. void ModifyPayloadTypesAndRemoveMidExtension( - cricket::SessionDescription* desc) { + std::unique_ptr& sdp) { int pt = 96; - for (ContentInfo& content : desc->contents()) { + for (ContentInfo& content : sdp->description()->contents()) { cricket::MediaContentDescription* media = content.media_description(); cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions(); extensions.erase(std::remove_if(extensions.begin(), extensions.end(), @@ -1154,9 +1158,10 @@ TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } -static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) { +static void MakeSpecCompliantMaxBundleOffer( + std::unique_ptr& sdp) { bool first = true; - for (cricket::ContentInfo& content : desc->contents()) { + for (cricket::ContentInfo& content : sdp->description()->contents()) { if (first) { first = false; continue; @@ -1164,7 +1169,8 @@ static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) { content.bundle_only = true; } first = true; - for (cricket::TransportInfo& transport : desc->transport_infos()) { + for (cricket::TransportInfo& transport : + sdp->description()->transport_infos()) { if (first) { first = false; continue; @@ -2567,9 +2573,10 @@ TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) { // Remove all but one audio/video codec (opus and VP8), and change the // casing of the caller's generated offer. - caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) { + caller()->SetGeneratedSdpMunger([](std::unique_ptr< + SessionDescriptionInterface>& sdp) { cricket::AudioContentDescription* audio = - GetFirstAudioContentDescription(description); + GetFirstAudioContentDescription(sdp->description()); ASSERT_NE(nullptr, audio); auto audio_codecs = audio->codecs(); audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(), @@ -2582,7 +2589,7 @@ TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) { audio->set_codecs(audio_codecs); cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(description); + GetFirstVideoContentDescription(sdp->description()); ASSERT_NE(nullptr, video); auto video_codecs = video->codecs(); video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(), @@ -3231,9 +3238,9 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, ConnectFakeSignaling(); caller()->AddVideoTrack(); callee()->AddVideoTrack(); - auto munger = [](cricket::SessionDescription* desc) { + auto munger = [](std::unique_ptr& sdp) { cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(desc); + GetFirstVideoContentDescription(sdp->description()); auto codecs = video->codecs(); for (auto&& codec : codecs) { if (codec.name == "H264") { @@ -3254,17 +3261,18 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, caller()->CreateAndSetAndSignalOffer(); ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); // Observe that after munging the parameter is present in generated SDP. - caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) { - cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(desc); - for (auto&& codec : video->codecs()) { - if (codec.name == "H264") { - std::string value; - EXPECT_TRUE( - codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value)); - } - } - }); + caller()->SetGeneratedSdpMunger( + [](std::unique_ptr& sdp) { + cricket::VideoContentDescription* video = + GetFirstVideoContentDescription(sdp->description()); + for (auto&& codec : video->codecs()) { + if (codec.name == "H264") { + std::string value; + EXPECT_TRUE( + codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value)); + } + } + }); caller()->CreateOfferAndWait(); } @@ -3785,24 +3793,25 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, auto send_transceiver = audio_transceiver_or_error.MoveValue(); // Munge the SDP to include NACK and RRTR on Opus, and remove all other // codecs. - caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { - cricket::MediaContentDescription* media = content.media_description(); - std::vector codecs = media->codecs(); - std::vector codecs_out; - for (cricket::Codec codec : codecs) { - if (codec.name == "opus") { - codec.AddFeedbackParam(cricket::FeedbackParam( - cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)); - codec.AddFeedbackParam(cricket::FeedbackParam( - cricket::kRtcpFbParamRrtr, cricket::kParamValueEmpty)); - codecs_out.push_back(codec); + caller()->SetGeneratedSdpMunger( + [](std::unique_ptr& sdp) { + for (ContentInfo& content : sdp->description()->contents()) { + cricket::MediaContentDescription* media = content.media_description(); + std::vector codecs = media->codecs(); + std::vector codecs_out; + for (cricket::Codec codec : codecs) { + if (codec.name == "opus") { + codec.AddFeedbackParam(cricket::FeedbackParam( + cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)); + codec.AddFeedbackParam(cricket::FeedbackParam( + cricket::kRtcpFbParamRrtr, cricket::kParamValueEmpty)); + codecs_out.push_back(codec); + } + } + EXPECT_FALSE(codecs_out.empty()); + media->set_codecs(codecs_out); } - } - EXPECT_FALSE(codecs_out.empty()); - media->set_codecs(codecs_out); - } - }); + }); caller()->CreateAndSetAndSignalOffer(); // Check for failure in helpers @@ -3835,22 +3844,23 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, VideoPacketLossCausesNack) { auto send_transceiver = video_transceiver_or_error.MoveValue(); // Munge the SDP to include NACK and RRTR on VP8, and remove all other // codecs. - caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { - cricket::MediaContentDescription* media = content.media_description(); - std::vector codecs = media->codecs(); - std::vector codecs_out; - for (cricket::Codec codec : codecs) { - if (codec.name == "VP8") { - ASSERT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( - cricket::kRtcpFbParamNack, cricket::kParamValueEmpty))); - codecs_out.push_back(codec); + caller()->SetGeneratedSdpMunger( + [](std::unique_ptr& sdp) { + for (ContentInfo& content : sdp->description()->contents()) { + cricket::MediaContentDescription* media = content.media_description(); + std::vector codecs = media->codecs(); + std::vector codecs_out; + for (cricket::Codec codec : codecs) { + if (codec.name == "VP8") { + ASSERT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( + cricket::kRtcpFbParamNack, cricket::kParamValueEmpty))); + codecs_out.push_back(codec); + } + } + EXPECT_FALSE(codecs_out.empty()); + media->set_codecs(codecs_out); } - } - EXPECT_FALSE(codecs_out.empty()); - media->set_codecs(codecs_out); - } - }); + }); caller()->CreateAndSetAndSignalOffer(); // Check for failure in helpers @@ -3877,14 +3887,181 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, PrAnswerStateTransitions) { ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); ConnectFakeSignaling(); caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack()); - callee()->SetAnswerWithPrAnswer(true); + caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack()); + + callee()->SetGeneratedSdpMunger( + [](std::unique_ptr& sdp) { + SetSdpType(sdp, SdpType::kPrAnswer); + }); + std::unique_ptr answer; + caller()->SetReceivedSdpMunger( + [&](std::unique_ptr& sdp) { + answer = sdp->Clone(); + }); caller()->CreateAndSetAndSignalOffer(); ASSERT_FALSE(HasFailure()); EXPECT_EQ(caller()->pc()->signaling_state(), PeerConnectionInterface::kHaveRemotePrAnswer); EXPECT_EQ(callee()->pc()->signaling_state(), PeerConnectionInterface::kHaveLocalPrAnswer); - // Note: there should be code here for applying the permanent answer. + + // // Apply the pranswer as a definitive one. + SetSdpType(answer, SdpType::kAnswer); + EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer))); + EXPECT_EQ(caller()->pc()->signaling_state(), + PeerConnectionInterface::kStable); +} + +// Let caller get a prAnswer followed by answer. +TEST_F(PeerConnectionIntegrationTestUnifiedPlan, + PrAnswerStateTransitionsAsymmetric) { + RTCConfiguration config; + ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); + ConnectFakeSignaling(); + caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack()); + caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack()); + + std::unique_ptr answer; + caller()->SetReceivedSdpMunger( + [&](std::unique_ptr& sdp) { + answer = sdp->Clone(); + SetSdpType(sdp, SdpType::kPrAnswer); + }); + caller()->CreateAndSetAndSignalOffer(); + ASSERT_FALSE(HasFailure()); + EXPECT_EQ(caller()->pc()->signaling_state(), + PeerConnectionInterface::kHaveRemotePrAnswer); + EXPECT_EQ(callee()->pc()->signaling_state(), + PeerConnectionInterface::kStable); + + // // Apply the pranswer as a definitive one. + EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer))); + EXPECT_EQ(caller()->pc()->signaling_state(), + PeerConnectionInterface::kStable); +} + +int ReassignPayloadIds(std::unique_ptr& sdp) { + int swaps = 0; + for (ContentInfo& content : sdp->description()->contents()) { + if (!content.media_description()) { + continue; + } + std::vector codecs = content.media_description()->codecs(); + int left = 0; + int right = codecs.size() - 1; + while (left < right) { + if (!codecs[left].IsMediaCodec()) { + left++; + continue; + } + if (!codecs[right].IsMediaCodec()) { + right--; + continue; + } + auto tmp = codecs[left].id; + codecs[left].id = codecs[right].id; + codecs[right].id = tmp; + left++; + right--; + swaps++; + } + content.media_description()->set_codecs(codecs); + } + return swaps; +} + +int SetNewSsrcs(std::unique_ptr& sdp) { + int assignments = 0; + std::unordered_set already_used_ssrcs; + for (ContentInfo& content : sdp->description()->contents()) { + if (!content.media_description()) { + continue; + } + for (const auto& stream : content.media_description()->streams()) { + for (const auto& ssrc : stream.ssrcs) { + already_used_ssrcs.insert(ssrc); + } + } + } + + Random random(/* random_seed= */ 77); + auto ssrc_generator = [&]() -> uint32_t { + do { + auto ssrc = random.Rand(1u, 0xFFFFFFF0u); + if (already_used_ssrcs.find(ssrc) == already_used_ssrcs.end()) { + already_used_ssrcs.insert(ssrc); + return ssrc; + } + } while (true); + }; + + for (ContentInfo& content : sdp->description()->contents()) { + if (!content.media_description()) { + continue; + } + for (auto& stream : content.media_description()->mutable_streams()) { + // Only reassign primary ssrc for now... + // but we should maybe also reassign ssrcs for ssrc groups?. + if (stream.ssrcs.size() == 1) { + assignments++; + stream.ssrcs[0] = ssrc_generator(); + } + } + } + return assignments; +} + +void SetNewFingerprint(std::unique_ptr& sdp) { + auto identity = rtc::SSLIdentity::Create("NewIdentity", rtc::KT_DEFAULT); + auto new_fingerprint = + rtc::SSLFingerprint::CreateUnique("sha-256", *identity.get()); + for (auto& transport_info : sdp->description()->transport_infos()) { + transport_info.description.identity_fingerprint = + absl::WrapUnique(new rtc::SSLFingerprint(*new_fingerprint.get())); + } +} + +TEST_F(PeerConnectionIntegrationTestUnifiedPlan, + PrAnswerStateTransitionsAsymmetricScrambled) { + RTCConfiguration config; + ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); + ConnectFakeSignaling(); + webrtc::RtpEncodingParameters init_send_encodings; + init_send_encodings.active = false; + caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {"name"}, + {init_send_encodings}); + caller()->pc()->AddTrack(caller()->CreateLocalVideoTrack(), {"name"}, + {init_send_encodings}); + callee()->pc()->AddTrack(callee()->CreateLocalAudioTrack(), {"name"}, + {init_send_encodings}); + callee()->pc()->AddTrack(callee()->CreateLocalVideoTrack(), {"name"}, + {init_send_encodings}); + + std::unique_ptr answer; + caller()->SetReceivedSdpMunger( + [&](std::unique_ptr& sdp) { + answer = sdp->Clone(); + SetSdpType(sdp, SdpType::kPrAnswer); + }); + caller()->CreateAndSetAndSignalOffer(); + + ASSERT_FALSE(HasFailure()); + ASSERT_EQ(caller()->pc()->signaling_state(), + PeerConnectionInterface::kHaveRemotePrAnswer); + ASSERT_EQ(callee()->pc()->signaling_state(), + PeerConnectionInterface::kStable); + + // Now scramble the answer sdp so that it (really!) different from the first + // prAnswer. + // Note: this is maybe {possibly...probably?} a spec violation. + ASSERT_GT(SetNewSsrcs(answer), 0); + ASSERT_GT(ReassignPayloadIds(answer), 0); + SetNewFingerprint(answer); + + // Apply the modified answer as a definitive one. + EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer))); + EXPECT_EQ(caller()->pc()->signaling_state(), + PeerConnectionInterface::kStable); } } // namespace diff --git a/pc/test/integration_test_helpers.cc b/pc/test/integration_test_helpers.cc index 7ffe4db432..9a439f41d8 100644 --- a/pc/test/integration_test_helpers.cc +++ b/pc/test/integration_test_helpers.cc @@ -18,15 +18,16 @@ PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() { return options; } -void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { +void RemoveSsrcsAndMsids(std::unique_ptr& sdp) { + for (ContentInfo& content : sdp->description()->contents()) { content.media_description()->mutable_streams().clear(); } - desc->set_msid_signaling(0); + sdp->description()->set_msid_signaling(0); } -void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { +void RemoveSsrcsAndKeepMsids( + std::unique_ptr& sdp) { + for (ContentInfo& content : sdp->description()->contents()) { std::string track_id; std::vector stream_ids; if (!content.media_description()->streams().empty()) { @@ -43,6 +44,13 @@ void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) { } } +void SetSdpType(std::unique_ptr& sdp, + SdpType sdpType) { + std::string str; + sdp->ToString(&str); + sdp = CreateSessionDescription(sdpType, str); +} + int FindFirstMediaStatsIndexByKind( const std::string& kind, const std::vector& inbound_rtps) { diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h index 458aa3a36d..5b9d632824 100644 --- a/pc/test/integration_test_helpers.h +++ b/pc/test/integration_test_helpers.h @@ -165,11 +165,16 @@ PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions(); // Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic" // attribute from received SDP, simulating a legacy endpoint. -void RemoveSsrcsAndMsids(cricket::SessionDescription* desc); +void RemoveSsrcsAndMsids(std::unique_ptr& desc); // Removes all stream information besides the stream ids, simulating an // endpoint that only signals a=msid lines to convey stream_ids. -void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc); +void RemoveSsrcsAndKeepMsids( + std::unique_ptr& desc); + +// Set SdpType. +void SetSdpType(std::unique_ptr& sdp, + SdpType sdpType); // Replaces the stream's primary SSRC and updates the first SSRC of all // ssrc-groups. @@ -265,14 +270,16 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, // used to test SDP being applied that a PeerConnection would normally not // generate, but a non-JSEP endpoint might. void SetReceivedSdpMunger( - std::function munger) { + std::function&)> + munger) { received_sdp_munger_ = std::move(munger); } // Similar to the above, but this is run on SDP immediately after it's // generated. void SetGeneratedSdpMunger( - std::function munger) { + std::function&)> + munger) { generated_sdp_munger_ = std::move(munger); } @@ -658,9 +665,21 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, candidates_expected_ = candidate_count; } - // For testing PR-Answer functionality - // If true, an offer will get a pr-answer back. - void SetAnswerWithPrAnswer(bool value) { answer_with_pr_answer_ = value; } + bool SetRemoteDescription(std::unique_ptr desc) { + auto observer = rtc::make_ref_counted(); + std::string str; + desc->ToString(&str); + RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription SDP:\n" << str; + pc()->SetRemoteDescription(std::move(desc), observer); // desc.release()); + RemoveUnusedVideoRenderers(); + EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); + auto err = observer->error(); + if (!err.ok()) { + RTC_LOG(LS_WARNING) << debug_name_ + << ": SetRemoteDescription error: " << err.message(); + } + return observer->error().ok(); + } private: // Constructor used by friend class PeerConnectionIntegrationBaseTest. @@ -736,7 +755,7 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, std::unique_ptr desc = CreateSessionDescription(SdpType::kOffer, msg); if (received_sdp_munger_) { - received_sdp_munger_(desc->description()); + received_sdp_munger_(desc); } EXPECT_TRUE(SetRemoteDescription(std::move(desc))); @@ -748,11 +767,6 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, } auto answer = CreateAnswer(); ASSERT_NE(nullptr, answer); - if (answer_with_pr_answer_) { - std::string answer_string; - answer->ToString(&answer_string); - answer = CreateSessionDescription(SdpType::kPrAnswer, answer_string); - } EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer))); } @@ -762,7 +776,7 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, std::unique_ptr desc = CreateSessionDescription(type, msg); if (received_sdp_munger_) { - received_sdp_munger_(desc->description()); + received_sdp_munger_(desc); } EXPECT_TRUE(SetRemoteDescription(std::move(desc))); @@ -786,7 +800,7 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, } auto description = observer->MoveDescription(); if (generated_sdp_munger_) { - generated_sdp_munger_(description->description()); + generated_sdp_munger_(description); } return description; } @@ -813,15 +827,6 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, return true; } - bool SetRemoteDescription(std::unique_ptr desc) { - auto observer = rtc::make_ref_counted(); - RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription"; - pc()->SetRemoteDescription(observer.get(), desc.release()); - RemoveUnusedVideoRenderers(); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - return observer->result(); - } - // This is a work around to remove unused fake_video_renderers from // transceivers that have either stopped or are no longer receiving. void RemoveUnusedVideoRenderers() { @@ -1059,8 +1064,10 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, SdpSemantics sdp_semantics_; PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_; - std::function received_sdp_munger_; - std::function generated_sdp_munger_; + std::function&)> + received_sdp_munger_; + std::function&)> + generated_sdp_munger_; std::function remote_offer_handler_; MockAsyncDnsResolver* remote_async_dns_resolver_ = nullptr; // Result variables for the mock DNS resolver @@ -1097,8 +1104,6 @@ class PeerConnectionIntegrationWrapper : public PeerConnectionObserver, uint64_t audio_concealed_stat_ = 0; std::string rtp_stats_id_; - bool answer_with_pr_answer_ = false; - ScopedTaskSafety task_safety_; friend class PeerConnectionIntegrationBaseTest;