Move MID/JsepTransport mappings into a new manager object.
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 <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34261}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 8a4955c462..a1feb98 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -41,8 +41,6 @@
visibility = [ "*" ]
defines = []
sources = [
- "bundle_manager.cc",
- "bundle_manager.h",
"channel.cc",
"channel.h",
"channel_interface.h",
@@ -58,6 +56,8 @@
"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 0228635..0000000
--- 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<cricket::ContentGroup>(*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<cricket::ContentGroup>& 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<cricket::ContentGroup>& 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 2e2aa77..0000000
--- 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 <memory>
-#include <string>
-#include <vector>
-
-#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<std::unique_ptr<cricket::ContentGroup>>& 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<std::unique_ptr<cricket::ContentGroup>> 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 0000000..42d374c
--- /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 <map>
+
+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<cricket::ContentGroup>(*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<cricket::ContentGroup>& 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<cricket::ContentGroup>& 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<cricket::JsepTransport> transport) {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ jsep_transports_by_name_[mid] = std::move(transport);
+}
+
+std::vector<cricket::JsepTransport*> JsepTransportCollection::Transports() {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ std::vector<cricket::JsepTransport*> 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 0000000..3078654
--- /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 <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#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<std::unique_ptr<cricket::ContentGroup>>& 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<std::unique_ptr<cricket::ContentGroup>> 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<bool(const std::string& mid,
+ cricket::JsepTransport* transport)>
+ map_change_callback,
+ std::function<void()> 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<cricket::JsepTransport> transport);
+ std::vector<cricket::JsepTransport*> 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<std::string, std::unique_ptr<cricket::JsepTransport>>
+ 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<std::string, cricket::JsepTransport*> mid_to_transport_
+ RTC_GUARDED_BY(sequence_checker_);
+ // Keep track of mids that have been mapped to transports. Used for rollback.
+ std::vector<std::string> pending_mids_ RTC_GUARDED_BY(sequence_checker_);
+ // Callback used to inform subscribers of altered transports.
+ const std::function<bool(const std::string& mid,
+ cricket::JsepTransport* transport)>
+ map_change_callback_;
+ // Callback used to inform subscribers of possibly altered state.
+ const std::function<void()> 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 413c940..f193f02 100644
--- a/pc/jsep_transport_controller.cc
+++ b/pc/jsep_transport_controller.cc
@@ -13,6 +13,7 @@
#include <stddef.h>
#include <algorithm>
+#include <functional>
#include <memory>
#include <utility>
@@ -59,6 +60,14 @@
: 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::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 @@
// 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 @@
<< "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 @@
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<webrtc::IceTransportInterface>
@@ -523,9 +526,7 @@
JsepTransportController::GetDtlsTransports() {
RTC_DCHECK_RUN_ON(network_thread_);
std::vector<cricket::DtlsTransportInternal*> 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 @@
}
}
if (type == SdpType::kAnswer) {
- pending_mids_.clear();
+ transports_.CommitTransports();
}
return RTCError::OK();
}
@@ -839,7 +840,7 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 2d912e5..a947075 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 @@
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 @@
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<std::string, std::unique_ptr<cricket::JsepTransport>>
- 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<std::string, cricket::JsepTransport*> mid_to_transport_
- RTC_GUARDED_BY(network_thread_);
- // Keep track of mids that have been mapped to transports. Used for rollback.
- std::vector<std::string> 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