diff --git a/api/jsep_ice_candidate.h b/api/jsep_ice_candidate.h index 4ee84cf79c..1a4247cb07 100644 --- a/api/jsep_ice_candidate.h +++ b/api/jsep_ice_candidate.h @@ -34,6 +34,8 @@ class RTC_EXPORT JsepIceCandidate : public IceCandidateInterface { JsepIceCandidate(const std::string& sdp_mid, int sdp_mline_index, const cricket::Candidate& candidate); + JsepIceCandidate(const JsepIceCandidate&) = delete; + JsepIceCandidate& operator=(const JsepIceCandidate&) = delete; ~JsepIceCandidate() override; // |err| may be null. bool Initialize(const std::string& sdp, SdpParseError* err); @@ -53,8 +55,6 @@ class RTC_EXPORT JsepIceCandidate : public IceCandidateInterface { std::string sdp_mid_; int sdp_mline_index_; cricket::Candidate candidate_; - - RTC_DISALLOW_COPY_AND_ASSIGN(JsepIceCandidate); }; // Implementation of IceCandidateCollection which stores JsepIceCandidates. @@ -64,6 +64,8 @@ class JsepCandidateCollection : public IceCandidateCollection { // Move constructor is defined so that a vector of JsepCandidateCollections // can be resized. JsepCandidateCollection(JsepCandidateCollection&& o); + // Returns a copy of the candidate collection. + JsepCandidateCollection Clone() const; size_t count() const override; bool HasCandidate(const IceCandidateInterface* candidate) const override; // Adds and takes ownership of the JsepIceCandidate. diff --git a/pc/jsep_ice_candidate.cc b/pc/jsep_ice_candidate.cc index 4e4542182a..6dacde629c 100644 --- a/pc/jsep_ice_candidate.cc +++ b/pc/jsep_ice_candidate.cc @@ -14,6 +14,11 @@ #include "pc/webrtc_sdp.h" +// This file contains JsepIceCandidate-related functions that are not +// included in api/jsep_ice_candidate.cc. Some of these link to SDP +// parsing/serializing functions, which some users may not want. +// TODO(bugs.webrtc.org/12330): Merge the two .cc files somehow. + namespace webrtc { IceCandidateInterface* CreateIceCandidate(const std::string& sdp_mid, @@ -49,6 +54,16 @@ JsepIceCandidate::JsepIceCandidate(const std::string& sdp_mid, JsepIceCandidate::~JsepIceCandidate() {} +JsepCandidateCollection JsepCandidateCollection::Clone() const { + JsepCandidateCollection new_collection; + for (const auto& candidate : candidates_) { + new_collection.candidates_.push_back(std::make_unique( + candidate->sdp_mid(), candidate->sdp_mline_index(), + candidate->candidate())); + } + return new_collection; +} + bool JsepIceCandidate::Initialize(const std::string& sdp, SdpParseError* err) { return SdpDeserializeCandidate(sdp, this, err); } diff --git a/pc/jsep_session_description.cc b/pc/jsep_session_description.cc index e0b23110a1..9de81947de 100644 --- a/pc/jsep_session_description.cc +++ b/pc/jsep_session_description.cc @@ -218,8 +218,12 @@ bool JsepSessionDescription::Initialize( std::unique_ptr JsepSessionDescription::Clone() const { auto new_description = std::make_unique(type_); - new_description->Initialize(description_->Clone(), session_id_, - session_version_); + new_description->session_id_ = session_id_; + new_description->session_version_ = session_version_; + new_description->description_ = description_->Clone(); + for (const auto& collection : candidate_collection_) { + new_description->candidate_collection_.push_back(collection.Clone()); + } return new_description; } diff --git a/pc/jsep_session_description_unittest.cc b/pc/jsep_session_description_unittest.cc index 7f83c085a7..d922a586c5 100644 --- a/pc/jsep_session_description_unittest.cc +++ b/pc/jsep_session_description_unittest.cc @@ -129,6 +129,33 @@ TEST_F(JsepSessionDescriptionTest, CloneDefault) { EXPECT_EQ(jsep_desc_->session_version(), new_desc->session_version()); } +TEST_F(JsepSessionDescriptionTest, CloneWithCandidates) { + cricket::Candidate candidate_v4( + cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", + rtc::SocketAddress("192.168.1.5", 1234), kCandidatePriority, "", "", + cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation); + cricket::Candidate candidate_v6( + cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", + rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "", + cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation); + + JsepIceCandidate jice_v4("audio", 0, candidate_v4); + JsepIceCandidate jice_v6("audio", 0, candidate_v6); + JsepIceCandidate jice_v4_video("video", 0, candidate_v4); + JsepIceCandidate jice_v6_video("video", 0, candidate_v6); + ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v4)); + ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v6)); + ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v4_video)); + ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v6_video)); + auto new_desc = jsep_desc_->Clone(); + EXPECT_EQ(jsep_desc_->type(), new_desc->type()); + std::string old_desc_string; + std::string new_desc_string; + EXPECT_TRUE(jsep_desc_->ToString(&old_desc_string)); + EXPECT_TRUE(new_desc->ToString(&new_desc_string)); + EXPECT_EQ(old_desc_string, new_desc_string); +} + // Test that number_of_mediasections() returns the number of media contents in // a session description. TEST_F(JsepSessionDescriptionTest, CheckSessionDescription) {