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/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