From 9dea393f17ed34a3e62366ac6e1275f8bef5dcda Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 10 Jun 2021 06:03:06 +0000 Subject: [PATCH] Move MID/JsepTransport mappings into a new manager object. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is part of the work to make Bundle handling understandable, so that we can get it to work right. Bug: webrtc:12837 Change-Id: I77f046b4bac2d9709460b3b956a2edc3df0cdaac Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221745 Commit-Queue: Harald Alvestrand Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/master@{#34261} --- pc/BUILD.gn | 4 +- pc/bundle_manager.cc | 49 --------- pc/bundle_manager.h | 54 ---------- pc/jsep_transport_collection.cc | 182 ++++++++++++++++++++++++++++++++ pc/jsep_transport_collection.h | 125 ++++++++++++++++++++++ pc/jsep_transport_controller.cc | 125 +++++++++------------- pc/jsep_transport_controller.h | 18 +--- 7 files changed, 362 insertions(+), 195 deletions(-) delete mode 100644 pc/bundle_manager.cc delete mode 100644 pc/bundle_manager.h create mode 100644 pc/jsep_transport_collection.cc create mode 100644 pc/jsep_transport_collection.h diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 8a4955c462..a1feb98d10 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -41,8 +41,6 @@ rtc_library("rtc_pc_base") { visibility = [ "*" ] defines = [] sources = [ - "bundle_manager.cc", - "bundle_manager.h", "channel.cc", "channel.h", "channel_interface.h", @@ -58,6 +56,8 @@ rtc_library("rtc_pc_base") { "ice_transport.h", "jsep_transport.cc", "jsep_transport.h", + "jsep_transport_collection.cc", + "jsep_transport_collection.h", "jsep_transport_controller.cc", "jsep_transport_controller.h", "media_session.cc", diff --git a/pc/bundle_manager.cc b/pc/bundle_manager.cc deleted file mode 100644 index 0228635998..0000000000 --- a/pc/bundle_manager.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2021 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pc/bundle_manager.h" - -namespace webrtc { - -void BundleManager::Update(const cricket::SessionDescription* description) { - bundle_groups_.clear(); - for (const cricket::ContentGroup* new_bundle_group : - description->GetGroupsByName(cricket::GROUP_TYPE_BUNDLE)) { - bundle_groups_.push_back( - std::make_unique(*new_bundle_group)); - } -} - -void BundleManager::DeleteMid(const cricket::ContentGroup* bundle_group, - const std::string& mid) { - // Remove the rejected content from the |bundle_group|. - // The const pointer arg is used to identify the group, we verify - // it before we use it to make a modification. - auto bundle_group_it = std::find_if( - bundle_groups_.begin(), bundle_groups_.end(), - [bundle_group](std::unique_ptr& group) { - return bundle_group == group.get(); - }); - RTC_DCHECK(bundle_group_it != bundle_groups_.end()); - (*bundle_group_it)->RemoveContentName(mid); -} - -void BundleManager::DeleteGroup(const cricket::ContentGroup* bundle_group) { - // Delete the BUNDLE group. - auto bundle_group_it = std::find_if( - bundle_groups_.begin(), bundle_groups_.end(), - [bundle_group](std::unique_ptr& group) { - return bundle_group == group.get(); - }); - RTC_DCHECK(bundle_group_it != bundle_groups_.end()); - bundle_groups_.erase(bundle_group_it); -} - -} // namespace webrtc diff --git a/pc/bundle_manager.h b/pc/bundle_manager.h deleted file mode 100644 index 2e2aa77f6d..0000000000 --- a/pc/bundle_manager.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2021 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef PC_BUNDLE_MANAGER_H_ -#define PC_BUNDLE_MANAGER_H_ - -#include -#include -#include - -#include "pc/session_description.h" - -namespace webrtc { -// This class manages information about RFC 8843 BUNDLE bundles -// in SDP descriptions. - -// This is a work-in-progress. Planned steps: -// 1) Move all Bundle-related data structures from JsepTransport -// into this class. -// 2) Move all Bundle-related functions into this class. -// 3) Move remaining Bundle-related logic into this class. -// Make data members private. -// 4) Refine interface to have comprehensible semantics. -// 5) Add unit tests. -// 6) Change the logic to do what's right. -class BundleManager { - public: - const std::vector>& bundle_groups() - const { - return bundle_groups_; - } - // Update the groups description. This completely replaces the group - // description with the one from the SessionDescription. - void Update(const cricket::SessionDescription* description); - // Delete a MID from the group that contains it. - void DeleteMid(const cricket::ContentGroup* bundle_group, - const std::string& mid); - // Delete a group. - void DeleteGroup(const cricket::ContentGroup* bundle_group); - - private: - std::vector> bundle_groups_; -}; - -} // namespace webrtc - -#endif // PC_BUNDLE_MANAGER_H_ diff --git a/pc/jsep_transport_collection.cc b/pc/jsep_transport_collection.cc new file mode 100644 index 0000000000..42d374ce51 --- /dev/null +++ b/pc/jsep_transport_collection.cc @@ -0,0 +1,182 @@ +/* + * Copyright 2021 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "pc/jsep_transport_collection.h" + +#include + +namespace webrtc { + +void BundleManager::Update(const cricket::SessionDescription* description) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + bundle_groups_.clear(); + for (const cricket::ContentGroup* new_bundle_group : + description->GetGroupsByName(cricket::GROUP_TYPE_BUNDLE)) { + bundle_groups_.push_back( + std::make_unique(*new_bundle_group)); + } +} + +void BundleManager::DeleteMid(const cricket::ContentGroup* bundle_group, + const std::string& mid) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Remove the rejected content from the |bundle_group|. + // The const pointer arg is used to identify the group, we verify + // it before we use it to make a modification. + auto bundle_group_it = std::find_if( + bundle_groups_.begin(), bundle_groups_.end(), + [bundle_group](std::unique_ptr& group) { + return bundle_group == group.get(); + }); + RTC_DCHECK(bundle_group_it != bundle_groups_.end()); + (*bundle_group_it)->RemoveContentName(mid); +} + +void BundleManager::DeleteGroup(const cricket::ContentGroup* bundle_group) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Delete the BUNDLE group. + auto bundle_group_it = std::find_if( + bundle_groups_.begin(), bundle_groups_.end(), + [bundle_group](std::unique_ptr& group) { + return bundle_group == group.get(); + }); + RTC_DCHECK(bundle_group_it != bundle_groups_.end()); + bundle_groups_.erase(bundle_group_it); +} + +void JsepTransportCollection::RegisterTransport( + const std::string& mid, + std::unique_ptr transport) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + jsep_transports_by_name_[mid] = std::move(transport); +} + +std::vector JsepTransportCollection::Transports() { + RTC_DCHECK_RUN_ON(&sequence_checker_); + std::vector result; + for (auto& kv : jsep_transports_by_name_) { + result.push_back(kv.second.get()); + } + return result; +} + +void JsepTransportCollection::DestroyAllTransports() { + RTC_DCHECK_RUN_ON(&sequence_checker_); + for (const auto& jsep_transport : jsep_transports_by_name_) { + map_change_callback_(jsep_transport.first, nullptr); + } + jsep_transports_by_name_.clear(); +} + +const cricket::JsepTransport* JsepTransportCollection::GetTransportByName( + const std::string& transport_name) const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + auto it = jsep_transports_by_name_.find(transport_name); + return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get(); +} + +cricket::JsepTransport* JsepTransportCollection::GetTransportByName( + const std::string& transport_name) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + auto it = jsep_transports_by_name_.find(transport_name); + return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get(); +} + +cricket::JsepTransport* JsepTransportCollection::GetTransportForMid( + const std::string& mid) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + auto it = mid_to_transport_.find(mid); + return it == mid_to_transport_.end() ? nullptr : it->second; +} + +const cricket::JsepTransport* JsepTransportCollection::GetTransportForMid( + const std::string& mid) const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + auto it = mid_to_transport_.find(mid); + return it == mid_to_transport_.end() ? nullptr : it->second; +} + +bool JsepTransportCollection::SetTransportForMid( + const std::string& mid, + cricket::JsepTransport* jsep_transport) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + RTC_DCHECK(jsep_transport); + + auto it = mid_to_transport_.find(mid); + if (it != mid_to_transport_.end() && it->second == jsep_transport) + return true; + + pending_mids_.push_back(mid); + + if (it == mid_to_transport_.end()) { + mid_to_transport_.insert(std::make_pair(mid, jsep_transport)); + } else { + it->second = jsep_transport; + } + + return map_change_callback_(mid, jsep_transport); +} + +void JsepTransportCollection::RemoveTransportForMid(const std::string& mid) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + bool ret = map_change_callback_(mid, nullptr); + // Calling OnTransportChanged with nullptr should always succeed, since it is + // only expected to fail when adding media to a transport (not removing). + RTC_DCHECK(ret); + + mid_to_transport_.erase(mid); +} + +void JsepTransportCollection::RollbackTransports() { + RTC_DCHECK_RUN_ON(&sequence_checker_); + for (auto&& mid : pending_mids_) { + RemoveTransportForMid(mid); + } + for (auto&& mid : pending_mids_) { + MaybeDestroyJsepTransport(mid); + } + pending_mids_.clear(); +} + +void JsepTransportCollection::CommitTransports() { + RTC_DCHECK_RUN_ON(&sequence_checker_); + pending_mids_.clear(); +} + +bool JsepTransportCollection::TransportInUse( + cricket::JsepTransport* jsep_transport) const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + for (const auto& kv : mid_to_transport_) { + if (kv.second == jsep_transport) { + return true; + } + } + return false; +} + +void JsepTransportCollection::MaybeDestroyJsepTransport( + const std::string& mid) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + auto it = jsep_transports_by_name_.find(mid); + if (it == jsep_transports_by_name_.end()) { + return; + } + + // Don't destroy the JsepTransport if there are still media sections referring + // to it. + if (TransportInUse(it->second.get())) { + return; + } + + jsep_transports_by_name_.erase(mid); + state_change_callback_(); +} + +} // namespace webrtc diff --git a/pc/jsep_transport_collection.h b/pc/jsep_transport_collection.h new file mode 100644 index 0000000000..307865490a --- /dev/null +++ b/pc/jsep_transport_collection.h @@ -0,0 +1,125 @@ +/* + * Copyright 2021 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef PC_JSEP_TRANSPORT_COLLECTION_H_ +#define PC_JSEP_TRANSPORT_COLLECTION_H_ + +#include +#include +#include +#include +#include + +#include "pc/jsep_transport.h" +#include "pc/session_description.h" + +namespace webrtc { + +// This class manages information about RFC 8843 BUNDLE bundles +// in SDP descriptions. + +// This is a work-in-progress. Planned steps: +// 1) Move all Bundle-related data structures from JsepTransport +// into this class. +// 2) Move all Bundle-related functions into this class. +// 3) Move remaining Bundle-related logic into this class. +// Make data members private. +// 4) Refine interface to have comprehensible semantics. +// 5) Add unit tests. +// 6) Change the logic to do what's right. +class BundleManager { + public: + BundleManager() { + // Allow constructor to be called on a different thread. + sequence_checker_.Detach(); + } + const std::vector>& bundle_groups() + const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + return bundle_groups_; + } + // Update the groups description. This completely replaces the group + // description with the one from the SessionDescription. + void Update(const cricket::SessionDescription* description); + // Delete a MID from the group that contains it. + void DeleteMid(const cricket::ContentGroup* bundle_group, + const std::string& mid); + // Delete a group. + void DeleteGroup(const cricket::ContentGroup* bundle_group); + + private: + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + std::vector> bundle_groups_ + RTC_GUARDED_BY(sequence_checker_); +}; + +// This class keeps the mapping of MIDs to transports. +// It is pulled out here because a lot of the code that deals with +// bundles end up modifying this map, and the two need to be consistent; +// the managers may merge. +class JsepTransportCollection { + public: + JsepTransportCollection(std::function + map_change_callback, + std::function state_change_callback) + : map_change_callback_(map_change_callback), + state_change_callback_(state_change_callback) { + // Allow constructor to be called on a different thread. + sequence_checker_.Detach(); + } + + void RegisterTransport(const std::string& mid, + std::unique_ptr transport); + std::vector Transports(); + void DestroyAllTransports(); + // Lookup a JsepTransport by the MID that was used to register it. + cricket::JsepTransport* GetTransportByName(const std::string& mid); + const cricket::JsepTransport* GetTransportByName( + const std::string& mid) const; + // Lookup a JsepTransport by any MID that refers to it. + cricket::JsepTransport* GetTransportForMid(const std::string& mid); + const cricket::JsepTransport* GetTransportForMid( + const std::string& mid) const; + bool SetTransportForMid(const std::string& mid, + cricket::JsepTransport* jsep_transport); + void RemoveTransportForMid(const std::string& mid); + // Roll back pending mid-to-transport mappings. + void RollbackTransports(); + // Commit pending mid-transport mappings (rollback is no longer possible). + void CommitTransports(); + // Returns true if any mid currently maps to this transport. + bool TransportInUse(cricket::JsepTransport* jsep_transport) const; + // Destroy a transport if it's no longer in use. + void MaybeDestroyJsepTransport(const std::string& mid); + + private: + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + // This member owns the JSEP transports. + std::map> + jsep_transports_by_name_ RTC_GUARDED_BY(sequence_checker_); + + // This keeps track of the mapping between media section + // (BaseChannel/SctpTransport) and the JsepTransport underneath. + std::map mid_to_transport_ + RTC_GUARDED_BY(sequence_checker_); + // Keep track of mids that have been mapped to transports. Used for rollback. + std::vector pending_mids_ RTC_GUARDED_BY(sequence_checker_); + // Callback used to inform subscribers of altered transports. + const std::function + map_change_callback_; + // Callback used to inform subscribers of possibly altered state. + const std::function state_change_callback_; +}; + +} // namespace webrtc + +#endif // PC_JSEP_TRANSPORT_COLLECTION_H_ diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index 413c940da8..f193f02750 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -59,6 +60,14 @@ JsepTransportController::JsepTransportController( : network_thread_(network_thread), port_allocator_(port_allocator), async_dns_resolver_factory_(async_dns_resolver_factory), + transports_( + [this](const std::string& mid, cricket::JsepTransport* transport) { + return OnTransportChanged(mid, transport); + }, + [this]() { + RTC_DCHECK_RUN_ON(network_thread_); + UpdateAggregateStates_n(); + }), config_(config), active_reset_srtp_params_(config.active_reset_srtp_params) { // The |transport_observer| is assumed to be non-null. @@ -179,8 +188,8 @@ void JsepTransportController::SetIceConfig(const cricket::IceConfig& config) { void JsepTransportController::SetNeedsIceRestartFlag() { RTC_DCHECK_RUN_ON(network_thread_); - for (auto& kv : jsep_transports_by_name_) { - kv.second->SetNeedsIceRestartFlag(); + for (auto& transport : transports_.Transports()) { + transport->SetNeedsIceRestartFlag(); } } @@ -233,8 +242,8 @@ bool JsepTransportController::SetLocalCertificate( // Set certificate for JsepTransport, which verifies it matches the // fingerprint in SDP, and DTLS transport. // Fallback from DTLS to SDES is not supported. - for (auto& kv : jsep_transports_by_name_) { - kv.second->SetLocalCertificate(certificate_); + for (auto& transport : transports_.Transports()) { + transport->SetLocalCertificate(certificate_); } for (auto& dtls : GetDtlsTransports()) { bool set_cert_success = dtls->SetLocalCertificate(certificate_); @@ -374,8 +383,8 @@ void JsepTransportController::SetActiveResetSrtpParams( << "Updating the active_reset_srtp_params for JsepTransportController: " << active_reset_srtp_params; active_reset_srtp_params_ = active_reset_srtp_params; - for (auto& kv : jsep_transports_by_name_) { - kv.second->SetActiveResetSrtpParams(active_reset_srtp_params); + for (auto& transport : transports_.Transports()) { + transport->SetActiveResetSrtpParams(active_reset_srtp_params); } } @@ -385,13 +394,7 @@ void JsepTransportController::RollbackTransports() { return; } RTC_DCHECK_RUN_ON(network_thread_); - for (auto&& mid : pending_mids_) { - RemoveTransportForMid(mid); - } - for (auto&& mid : pending_mids_) { - MaybeDestroyJsepTransport(mid); - } - pending_mids_.clear(); + transports_.RollbackTransports(); } rtc::scoped_refptr @@ -523,9 +526,7 @@ std::vector JsepTransportController::GetDtlsTransports() { RTC_DCHECK_RUN_ON(network_thread_); std::vector dtls_transports; - for (auto it = jsep_transports_by_name_.begin(); - it != jsep_transports_by_name_.end(); ++it) { - auto jsep_transport = it->second.get(); + for (auto jsep_transport : transports_.Transports()) { RTC_DCHECK(jsep_transport); if (jsep_transport->rtp_dtls_transport()) { dtls_transports.push_back(jsep_transport->rtp_dtls_transport()); @@ -661,7 +662,7 @@ RTCError JsepTransportController::ApplyDescription_n( } } if (type == SdpType::kAnswer) { - pending_mids_.clear(); + transports_.CommitTransports(); } return RTCError::OK(); } @@ -839,7 +840,7 @@ void JsepTransportController::HandleRejectedContent( // Rejecting a BUNDLE group's first mid means we are rejecting the entire // group. for (const auto& content_name : bundle_group->content_names()) { - RemoveTransportForMid(content_name); + transports_.RemoveTransportForMid(content_name); // We are about to delete this BUNDLE group, erase all mappings to it. it = established_bundle_groups_by_mid.find(content_name); RTC_DCHECK(it != established_bundle_groups_by_mid.end()); @@ -848,7 +849,7 @@ void JsepTransportController::HandleRejectedContent( // Delete the BUNDLE group. bundles_.DeleteGroup(bundle_group); } else { - RemoveTransportForMid(content_info.name); + transports_.RemoveTransportForMid(content_info.name); if (bundle_group) { // Remove the rejected content from the |bundle_group|. bundles_.DeleteMid(bundle_group, content_info.name); @@ -868,7 +869,7 @@ bool JsepTransportController::HandleBundledContent( // If the content is bundled, let the // BaseChannel/SctpTransport change the RtpTransport/DtlsTransport first, // then destroy the cricket::JsepTransport. - if (SetTransportForMid(content_info.name, jsep_transport)) { + if (transports_.SetTransportForMid(content_info.name, jsep_transport)) { // TODO(bugs.webrtc.org/9719) For media transport this is far from ideal, // because it means that we first create media transport and start // connecting it, and then we destroy it. We will need to address it before @@ -879,41 +880,6 @@ bool JsepTransportController::HandleBundledContent( return false; } -bool JsepTransportController::SetTransportForMid( - const std::string& mid, - cricket::JsepTransport* jsep_transport) { - TRACE_EVENT0("webrtc", "JsepTransportController::SetTransportForMid"); - RTC_DCHECK_RUN_ON(network_thread_); - RTC_DCHECK(jsep_transport); - - auto it = mid_to_transport_.find(mid); - if (it != mid_to_transport_.end() && it->second == jsep_transport) - return true; - - pending_mids_.push_back(mid); - - if (it == mid_to_transport_.end()) { - mid_to_transport_.insert(std::make_pair(mid, jsep_transport)); - } else { - it->second = jsep_transport; - } - - return config_.transport_observer->OnTransportChanged( - mid, jsep_transport->rtp_transport(), jsep_transport->RtpDtlsTransport(), - jsep_transport->data_channel_transport()); -} - -void JsepTransportController::RemoveTransportForMid(const std::string& mid) { - RTC_DCHECK_RUN_ON(network_thread_); - bool ret = config_.transport_observer->OnTransportChanged(mid, nullptr, - nullptr, nullptr); - // Calling OnTransportChanged with nullptr should always succeed, since it is - // only expected to fail when adding media to a transport (not removing). - RTC_DCHECK(ret); - - mid_to_transport_.erase(mid); -} - cricket::JsepTransportDescription JsepTransportController::CreateJsepTransportDescription( const cricket::ContentInfo& content_info, @@ -1024,26 +990,22 @@ int JsepTransportController::GetRtpAbsSendTimeHeaderExtensionId( const cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid( const std::string& mid) const { - auto it = mid_to_transport_.find(mid); - return it == mid_to_transport_.end() ? nullptr : it->second; + return transports_.GetTransportForMid(mid); } cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid( const std::string& mid) { - auto it = mid_to_transport_.find(mid); - return it == mid_to_transport_.end() ? nullptr : it->second; + return transports_.GetTransportForMid(mid); } const cricket::JsepTransport* JsepTransportController::GetJsepTransportByName( const std::string& transport_name) const { - auto it = jsep_transports_by_name_.find(transport_name); - return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get(); + return transports_.GetTransportByName(transport_name); } cricket::JsepTransport* JsepTransportController::GetJsepTransportByName( const std::string& transport_name) { - auto it = jsep_transports_by_name_.find(transport_name); - return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get(); + return transports_.GetTransportByName(transport_name); } RTCError JsepTransportController::MaybeCreateJsepTransport( @@ -1116,9 +1078,9 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( jsep_transport->SignalRtcpMuxActive.connect( this, &JsepTransportController::UpdateAggregateStates_n); - SetTransportForMid(content_info.name, jsep_transport.get()); + transports_.SetTransportForMid(content_info.name, jsep_transport.get()); - jsep_transports_by_name_[content_info.name] = std::move(jsep_transport); + transports_.RegisterTransport(content_info.name, std::move(jsep_transport)); UpdateAggregateStates_n(); return RTCError::OK(); } @@ -1133,23 +1095,15 @@ void JsepTransportController::MaybeDestroyJsepTransport( // Don't destroy the JsepTransport if there are still media sections referring // to it. - for (const auto& kv : mid_to_transport_) { - if (kv.second == jsep_transport) { - return; - } + if (transports_.TransportInUse(jsep_transport)) { + return; } - - jsep_transports_by_name_.erase(mid); + transports_.MaybeDestroyJsepTransport(mid); UpdateAggregateStates_n(); } void JsepTransportController::DestroyAllJsepTransports_n() { - for (const auto& jsep_transport : jsep_transports_by_name_) { - config_.transport_observer->OnTransportChanged(jsep_transport.first, - nullptr, nullptr, nullptr); - } - - jsep_transports_by_name_.clear(); + transports_.DestroyAllTransports(); } void JsepTransportController::SetIceRole_n(cricket::IceRole ice_role) { @@ -1467,4 +1421,21 @@ void JsepTransportController::OnDtlsHandshakeError( config_.on_dtls_handshake_error_(error); } +bool JsepTransportController::OnTransportChanged( + const std::string& mid, + cricket::JsepTransport* jsep_transport) { + if (config_.transport_observer) { + if (jsep_transport) { + return config_.transport_observer->OnTransportChanged( + mid, jsep_transport->rtp_transport(), + jsep_transport->RtpDtlsTransport(), + jsep_transport->data_channel_transport()); + } else { + return config_.transport_observer->OnTransportChanged(mid, nullptr, + nullptr, nullptr); + } + } + return false; +} + } // namespace webrtc diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h index 2d912e5ae9..a9470757e6 100644 --- a/pc/jsep_transport_controller.h +++ b/pc/jsep_transport_controller.h @@ -44,11 +44,11 @@ #include "p2p/base/port_allocator.h" #include "p2p/base/transport_description.h" #include "p2p/base/transport_info.h" -#include "pc/bundle_manager.h" #include "pc/channel.h" #include "pc/dtls_srtp_transport.h" #include "pc/dtls_transport.h" #include "pc/jsep_transport.h" +#include "pc/jsep_transport_collection.h" #include "pc/rtp_transport.h" #include "pc/rtp_transport_internal.h" #include "pc/sctp_transport.h" @@ -336,10 +336,6 @@ class JsepTransportController : public sigslot::has_slots<> { const cricket::ContentGroup& bundle_group) RTC_RUN_ON(network_thread_); - bool SetTransportForMid(const std::string& mid, - cricket::JsepTransport* jsep_transport); - void RemoveTransportForMid(const std::string& mid); - cricket::JsepTransportDescription CreateJsepTransportDescription( const cricket::ContentInfo& content_info, const cricket::TransportInfo& transport_info, @@ -453,18 +449,14 @@ class JsepTransportController : public sigslot::has_slots<> { void OnDtlsHandshakeError(rtc::SSLHandshakeError error); + bool OnTransportChanged(const std::string& mid, + cricket::JsepTransport* transport); + rtc::Thread* const network_thread_ = nullptr; cricket::PortAllocator* const port_allocator_ = nullptr; AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_ = nullptr; - std::map> - jsep_transports_by_name_ RTC_GUARDED_BY(network_thread_); - // This keeps track of the mapping between media section - // (BaseChannel/SctpTransport) and the JsepTransport underneath. - std::map mid_to_transport_ - RTC_GUARDED_BY(network_thread_); - // Keep track of mids that have been mapped to transports. Used for rollback. - std::vector pending_mids_ RTC_GUARDED_BY(network_thread_); + JsepTransportCollection transports_ RTC_GUARDED_BY(network_thread_); // Aggregate states for Transports. // standardized_ice_connection_state_ is intended to replace // ice_connection_state, see bugs.webrtc.org/9308