Change RTCStatsCollector to only access channels from signaling thread

Previously, the RTCStatsCollector needed to ask the voice/video
channel for its transport name in order to generate transport
level stats. That would happen on the networking thread which was
unsafe because the voice/video channel could have disappeared in
the duration of the asynchronous thread hop from the signaling
thread to the networking thread. This changes the networking stats
code to check a saved map that tracks the transport name for each
voice/video channel.

Bug: None
Change-Id: I1f03ba8c0526eaa4419f660f18b8b9da62c3f932
Reviewed-on: https://webrtc-review.googlesource.com/33660
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21332}
diff --git a/pc/channel.h b/pc/channel.h
index 73769b0..9e42811 100644
--- a/pc/channel.h
+++ b/pc/channel.h
@@ -207,6 +207,12 @@
   // an RtpTransport in a more explicit way.
   bool HandlesPayloadType(int payload_type) const;
 
+  // Used by the RTCStatsCollector tests to set the transport name without
+  // creating RtpTransports.
+  void set_transport_name_for_testing(const std::string& transport_name) {
+    transport_name_ = transport_name;
+  }
+
  protected:
   virtual MediaChannel* media_channel() const { return media_channel_.get(); }
 
diff --git a/pc/rtcstatscollector.cc b/pc/rtcstatscollector.cc
index 915aabf..24444f3 100644
--- a/pc/rtcstatscollector.cc
+++ b/pc/rtcstatscollector.cc
@@ -76,16 +76,6 @@
       rtc::ToString<>(channel_component);
 }
 
-std::string RTCTransportStatsIDFromBaseChannel(
-    const std::map<std::string, std::string>& proxy_to_transport,
-    const cricket::BaseChannel& base_channel) {
-  auto proxy_it = proxy_to_transport.find(base_channel.content_name());
-  if (proxy_it == proxy_to_transport.cend())
-    return "";
-  return RTCTransportStatsIDFromTransportChannel(
-      proxy_it->second, cricket::ICE_CANDIDATE_COMPONENT_RTP);
-}
-
 std::string RTCInboundRTPStreamStatsIDFromSSRC(bool audio, uint32_t ssrc) {
   return audio ? "RTCInboundRTPAudioStream_" + rtc::ToString<>(ssrc)
                : "RTCInboundRTPVideoStream_" + rtc::ToString<>(ssrc);
@@ -753,8 +743,8 @@
     ProduceIceCandidateAndPairStats_n(timestamp_us, *session_stats,
                                       track_media_info_map_->video_media_info(),
                                       call_stats_, report.get());
-    ProduceRTPStreamStats_n(
-        timestamp_us, *session_stats, *track_media_info_map_, report.get());
+    ProduceRTPStreamStats_n(timestamp_us, *session_stats, *channel_name_pairs_,
+                            *track_media_info_map_, report.get());
     ProduceTransportStats_n(
         timestamp_us, *session_stats, transport_cert_stats, report.get());
   }
@@ -993,16 +983,20 @@
 }
 
 void RTCStatsCollector::ProduceRTPStreamStats_n(
-    int64_t timestamp_us, const SessionStats& session_stats,
+    int64_t timestamp_us,
+    const SessionStats& session_stats,
+    const ChannelNamePairs& channel_name_pairs,
     const TrackMediaInfoMap& track_media_info_map,
     RTCStatsReport* report) const {
   RTC_DCHECK(network_thread_->IsCurrent());
 
   // Audio
   if (track_media_info_map.voice_media_info()) {
-    std::string transport_id = RTCTransportStatsIDFromBaseChannel(
-        session_stats.proxy_to_transport, *pc_->voice_channel());
-    RTC_DCHECK(!transport_id.empty());
+    RTC_DCHECK(channel_name_pairs.voice);
+    const std::string& transport_name =
+        (*channel_name_pairs.voice).transport_name;
+    std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+        transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
     // Inbound
     for (const cricket::VoiceReceiverInfo& voice_receiver_info :
          track_media_info_map.voice_media_info()->receivers) {
@@ -1062,9 +1056,11 @@
   }
   // Video
   if (track_media_info_map.video_media_info()) {
-    std::string transport_id = RTCTransportStatsIDFromBaseChannel(
-        session_stats.proxy_to_transport, *pc_->video_channel());
-    RTC_DCHECK(!transport_id.empty());
+    RTC_DCHECK(channel_name_pairs.video);
+    const std::string& transport_name =
+        (*channel_name_pairs.video).transport_name;
+    std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+        transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
     // Inbound
     for (const cricket::VideoReceiverInfo& video_receiver_info :
          track_media_info_map.video_media_info()->receivers) {
diff --git a/pc/rtcstatscollector.h b/pc/rtcstatscollector.h
index 6effe73..d73a764 100644
--- a/pc/rtcstatscollector.h
+++ b/pc/rtcstatscollector.h
@@ -118,10 +118,11 @@
   void ProducePeerConnectionStats_s(
       int64_t timestamp_us, RTCStatsReport* report) const;
   // Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
-  void ProduceRTPStreamStats_n(
-      int64_t timestamp_us, const SessionStats& session_stats,
-      const TrackMediaInfoMap& track_media_info_map,
-      RTCStatsReport* report) const;
+  void ProduceRTPStreamStats_n(int64_t timestamp_us,
+                               const SessionStats& session_stats,
+                               const ChannelNamePairs& channel_name_pairs,
+                               const TrackMediaInfoMap& track_media_info_map,
+                               RTCStatsReport* report) const;
   // Produces |RTCTransportStats|.
   void ProduceTransportStats_n(
       int64_t timestamp_us, const SessionStats& session_stats,
@@ -158,6 +159,7 @@
   std::unique_ptr<ChannelNamePairs> channel_name_pairs_;
   std::unique_ptr<TrackMediaInfoMap> track_media_info_map_;
   std::map<MediaStreamTrackInterface*, std::string> track_to_id_;
+
   Call::Stats call_stats_;
 
   // A timestamp, in microseconds, that is based on a timer that is
diff --git a/pc/rtcstatscollector_unittest.cc b/pc/rtcstatscollector_unittest.cc
index 8047dde..c50111c 100644
--- a/pc/rtcstatscollector_unittest.cc
+++ b/pc/rtcstatscollector_unittest.cc
@@ -1807,6 +1807,7 @@
       test_->signaling_thread(), test_->media_engine(),
       rtc::WrapUnique(voice_media_channel), "VoiceContentName",
       kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
+  voice_channel.set_transport_name_for_testing("TransportName");
 
   test_->SetupRemoteTrackAndReceiver(
       cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", 1);
@@ -1886,6 +1887,7 @@
       test_->worker_thread(), test_->network_thread(),
       test_->signaling_thread(), rtc::WrapUnique(video_media_channel),
       "VideoContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
+  video_channel.set_transport_name_for_testing("TransportName");
 
   test_->SetupRemoteTrackAndReceiver(
       cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", 1);
@@ -1988,6 +1990,7 @@
       test_->signaling_thread(), test_->media_engine(),
       rtc::WrapUnique(voice_media_channel), "VoiceContentName",
       kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
+  voice_channel.set_transport_name_for_testing("TransportName");
 
   test_->SetupLocalTrackAndSender(
       cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID", 1);
@@ -2065,6 +2068,7 @@
       test_->worker_thread(), test_->network_thread(),
       test_->signaling_thread(), rtc::WrapUnique(video_media_channel),
       "VideoContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
+  video_channel.set_transport_name_for_testing("TransportName");
 
   test_->SetupLocalTrackAndSender(
       cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID", 1);