Add DTLSTransport info into sender/receiver state.

This is in preparation for letting Chrome extract DTLSTransport
information after SLD/SRD instead of doing it on-demand.

Bug: chromium:907849
Change-Id: Iac6b174c98d3d14136e1fd25bce4a9292f6c8b41
Reviewed-on: https://webrtc-review.googlesource.com/c/116984
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26289}
diff --git a/api/dtls_transport_interface.h b/api/dtls_transport_interface.h
index abe7378..1faf3f5 100644
--- a/api/dtls_transport_interface.h
+++ b/api/dtls_transport_interface.h
@@ -23,7 +23,9 @@
   kConnecting,  // In the process of negotiating a secure connection.
   kConnected,   // Completed negotiation and verified fingerprints.
   kClosed,      // Intentionally closed.
-  kFailed  // Failure due to an error or failing to verify a remote fingerprint.
+  kFailed,      // Failure due to an error or failing to verify a remote
+                // fingerprint.
+  kNumValues
 };
 
 // This object gives snapshot information about the changeable state of a
diff --git a/api/rtp_receiver_interface.cc b/api/rtp_receiver_interface.cc
index d8bb3d3..52f72df 100644
--- a/api/rtp_receiver_interface.cc
+++ b/api/rtp_receiver_interface.cc
@@ -53,4 +53,9 @@
   return nullptr;
 }
 
+rtc::scoped_refptr<DtlsTransportInterface>
+RtpReceiverInterface::dtls_transport() const {
+  return nullptr;
+}
+
 }  // namespace webrtc
diff --git a/api/rtp_receiver_interface.h b/api/rtp_receiver_interface.h
index 12c9d95..e7fa0bf 100644
--- a/api/rtp_receiver_interface.h
+++ b/api/rtp_receiver_interface.h
@@ -18,6 +18,7 @@
 #include <vector>
 
 #include "api/crypto/frame_decryptor_interface.h"
+#include "api/dtls_transport_interface.h"
 #include "api/media_stream_interface.h"
 #include "api/media_types.h"
 #include "api/proxy.h"
@@ -92,6 +93,13 @@
 class RtpReceiverInterface : public rtc::RefCountInterface {
  public:
   virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
+
+  // The dtlsTransport attribute exposes the DTLS transport on which the
+  // media is received. It may be null.
+  // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-transport
+  // TODO(https://bugs.webrtc.org/907849) remove default implementation
+  virtual rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const;
+
   // The list of streams that |track| is associated with. This is the same as
   // the [[AssociatedRemoteMediaStreams]] internal slot in the spec.
   // https://w3c.github.io/webrtc-pc/#dfn-associatedremotemediastreams
@@ -146,6 +154,7 @@
 BEGIN_SIGNALING_PROXY_MAP(RtpReceiver)
 PROXY_SIGNALING_THREAD_DESTRUCTOR()
 PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track)
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<DtlsTransportInterface>, dtls_transport)
 PROXY_CONSTMETHOD0(std::vector<std::string>, stream_ids)
 PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<MediaStreamInterface>>,
                    streams)
diff --git a/api/rtp_sender_interface.cc b/api/rtp_sender_interface.cc
index 68747ea..d23fd18 100644
--- a/api/rtp_sender_interface.cc
+++ b/api/rtp_sender_interface.cc
@@ -25,4 +25,9 @@
   return {};
 }
 
+rtc::scoped_refptr<DtlsTransportInterface> RtpSenderInterface::dtls_transport()
+    const {
+  return nullptr;
+}
+
 }  // namespace webrtc
diff --git a/api/rtp_sender_interface.h b/api/rtp_sender_interface.h
index c1dc716..6397938 100644
--- a/api/rtp_sender_interface.h
+++ b/api/rtp_sender_interface.h
@@ -18,6 +18,7 @@
 #include <vector>
 
 #include "api/crypto/frame_encryptor_interface.h"
+#include "api/dtls_transport_interface.h"
 #include "api/dtmf_sender_interface.h"
 #include "api/media_stream_interface.h"
 #include "api/media_types.h"
@@ -36,6 +37,12 @@
   virtual bool SetTrack(MediaStreamTrackInterface* track) = 0;
   virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
 
+  // The dtlsTransport attribute exposes the DTLS transport on which the
+  // media is sent. It may be null.
+  // https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-transport
+  // TODO(https://bugs.webrtc.org/907849) remove default implementation
+  virtual rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const;
+
   // Returns primary SSRC used by this sender for sending media.
   // Returns 0 if not yet determined.
   // TODO(deadbeef): Change to absl::optional.
@@ -91,6 +98,7 @@
 PROXY_SIGNALING_THREAD_DESTRUCTOR()
 PROXY_METHOD1(bool, SetTrack, MediaStreamTrackInterface*)
 PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track)
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<DtlsTransportInterface>, dtls_transport)
 PROXY_CONSTMETHOD0(uint32_t, ssrc)
 PROXY_CONSTMETHOD0(cricket::MediaType, media_type)
 PROXY_CONSTMETHOD0(std::string, id)
diff --git a/logging/BUILD.gn b/logging/BUILD.gn
index bc7b3c0..c39833b 100644
--- a/logging/BUILD.gn
+++ b/logging/BUILD.gn
@@ -421,6 +421,7 @@
   deps = [
     ":rtc_event_log_api",
     "../api:libjingle_logging_api",
+    "../api:libjingle_peerconnection_api",
     "../rtc_base:rtc_base_approved",
     "//third_party/abseil-cpp/absl/memory",
   ]
diff --git a/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h b/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
index e76cfe9..b61cb33 100644
--- a/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
+++ b/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
@@ -13,19 +13,11 @@
 
 #include <memory>
 
+#include "api/dtls_transport_interface.h"
 #include "logging/rtc_event_log/events/rtc_event.h"
 
 namespace webrtc {
 
-enum class DtlsTransportState {
-  kNew,
-  kConnecting,
-  kConnected,
-  kClosed,
-  kFailed,
-  kNumValues
-};
-
 class RtcEventDtlsTransportState : public RtcEvent {
  public:
   explicit RtcEventDtlsTransportState(DtlsTransportState state);
diff --git a/pc/jsep_transport.h b/pc/jsep_transport.h
index 648fe29..21747a6 100644
--- a/pc/jsep_transport.h
+++ b/pc/jsep_transport.h
@@ -189,7 +189,7 @@
     }
   }
 
-  rtc::scoped_refptr<webrtc::DtlsTransportInterface> RtpDtlsTransport() {
+  rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport() {
     return rtp_dtls_transport_;
   }
 
diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc
index 926d71d..a7d1fd7 100644
--- a/pc/jsep_transport_controller.cc
+++ b/pc/jsep_transport_controller.cc
@@ -173,7 +173,7 @@
   return jsep_transport->rtcp_dtls_transport();
 }
 
-rtc::scoped_refptr<webrtc::DtlsTransportInterface>
+rtc::scoped_refptr<webrtc::DtlsTransport>
 JsepTransportController::LookupDtlsTransportByMid(const std::string& mid) {
   auto jsep_transport = GetJsepTransportForMid(mid);
   if (!jsep_transport) {
diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h
index e57b7d8..e160be3 100644
--- a/pc/jsep_transport_controller.h
+++ b/pc/jsep_transport_controller.h
@@ -117,7 +117,7 @@
   const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
       const std::string& mid) const;
   // Gets the externally sharable version of the DtlsTransport.
-  rtc::scoped_refptr<webrtc::DtlsTransportInterface> LookupDtlsTransportByMid(
+  rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid(
       const std::string& mid);
 
   MediaTransportInterface* GetMediaTransport(const std::string& mid) const;
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 2d68c81..41fadd8 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -2106,6 +2106,18 @@
     std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
     std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
     for (auto transceiver : transceivers_) {
+      // 2.2.7.1.1.(6-9): Set sender and receiver's transport slots.
+      // Note that code paths that don't set MID won't be able to use
+      // information about DTLS transports.
+      if (transceiver->mid()) {
+        auto dtls_transport =
+            LookupDtlsTransportByMidInternal(*transceiver->mid());
+        transceiver->internal()->sender_internal()->set_transport(
+            dtls_transport);
+        transceiver->internal()->receiver_internal()->set_transport(
+            dtls_transport);
+      }
+
       const ContentInfo* content =
           FindMediaSectionForTransceiver(transceiver, local_description());
       if (!content) {
@@ -2548,7 +2560,7 @@
           now_receiving_transceivers.push_back(transceiver);
         }
       }
-      // 2.2.8.1.7: If direction is "sendonly" or "inactive", and transceiver's
+      // 2.2.8.1.9: If direction is "sendonly" or "inactive", and transceiver's
       // [[FiredDirection]] slot is either "sendrecv" or "recvonly", process the
       // removal of a remote track for the media description, given transceiver,
       // removeList, and muteTracks.
@@ -2558,16 +2570,25 @@
         ProcessRemovalOfRemoteTrack(transceiver, &remove_list,
                                     &removed_streams);
       }
-      // 2.2.8.1.8: Set transceiver's [[FiredDirection]] slot to direction.
+      // 2.2.8.1.10: Set transceiver's [[FiredDirection]] slot to direction.
       transceiver->internal()->set_fired_direction(local_direction);
-      // 2.2.8.1.9: If description is of type "answer" or "pranswer", then run
+      // 2.2.8.1.11: If description is of type "answer" or "pranswer", then run
       // the following steps:
       if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
-        // 2.2.8.1.9.1: Set transceiver's [[CurrentDirection]] slot to
+        // 2.2.8.1.11.1: Set transceiver's [[CurrentDirection]] slot to
         // direction.
         transceiver->internal()->set_current_direction(local_direction);
+        // 2.2.8.1.11.[3-6]: Set the transport internal slots.
+        if (transceiver->mid()) {
+          auto dtls_transport =
+              LookupDtlsTransportByMidInternal(*transceiver->mid());
+          transceiver->internal()->sender_internal()->set_transport(
+              dtls_transport);
+          transceiver->internal()->receiver_internal()->set_transport(
+              dtls_transport);
+        }
       }
-      // 2.2.8.1.10: If the media description is rejected, and transceiver is
+      // 2.2.8.1.12: If the media description is rejected, and transceiver is
       // not already stopped, stop the RTCRtpTransceiver transceiver.
       if (content->rejected && !transceiver->stopped()) {
         RTC_LOG(LS_INFO) << "Stopping transceiver for MID=" << content->name
@@ -3445,6 +3466,11 @@
   return transport_controller_->LookupDtlsTransportByMid(mid);
 }
 
+rtc::scoped_refptr<DtlsTransport>
+PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
+  return transport_controller_->LookupDtlsTransportByMid(mid);
+}
+
 const SessionDescriptionInterface* PeerConnection::local_description() const {
   return pending_local_description_ ? pending_local_description_.get()
                                     : current_local_description_.get();
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index b11c867..ca92d76 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -197,6 +197,8 @@
 
   rtc::scoped_refptr<DtlsTransportInterface> LookupDtlsTransportByMid(
       const std::string& mid) override;
+  rtc::scoped_refptr<DtlsTransport> LookupDtlsTransportByMidInternal(
+      const std::string& mid);
 
   RTC_DEPRECATED bool StartRtcEventLog(rtc::PlatformFile file,
                                        int64_t max_size_bytes) override;
diff --git a/pc/peer_connection_signaling_unittest.cc b/pc/peer_connection_signaling_unittest.cc
index ed76753..340d472 100644
--- a/pc/peer_connection_signaling_unittest.cc
+++ b/pc/peer_connection_signaling_unittest.cc
@@ -108,6 +108,28 @@
     return wrapper;
   }
 
+  int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
+    std::set<DtlsTransportInterface*> transports;
+    auto transceivers = pc_wrapper->pc()->GetTransceivers();
+
+    for (auto& transceiver : transceivers) {
+      if (transceiver->sender()->dtls_transport()) {
+        EXPECT_TRUE(transceiver->receiver()->dtls_transport());
+        EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
+                  transceiver->receiver()->dtls_transport().get());
+        transports.insert(transceiver->sender()->dtls_transport().get());
+      } else {
+        // If one transceiver is missing, they all should be.
+        EXPECT_EQ(0UL, transports.size());
+      }
+    }
+    return transports.size();
+  }
+
+  bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
+    return NumberOfDtlsTransports(pc_wrapper) > 0;
+  }
+
   std::unique_ptr<rtc::VirtualSocketServer> vss_;
   rtc::AutoSocketServerThread main_;
   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
@@ -505,4 +527,74 @@
                         Values(SdpSemantics::kPlanB,
                                SdpSemantics::kUnifiedPlan));
 
+class PeerConnectionSignalingUnifiedPlanTest
+    : public PeerConnectionSignalingBaseTest {
+ protected:
+  PeerConnectionSignalingUnifiedPlanTest()
+      : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
+};
+
+// Test that transports are shown in the sender/receiver API after offer/answer.
+// This only works in Unified Plan.
+TEST_F(PeerConnectionSignalingUnifiedPlanTest,
+       DtlsTransportsInstantiateInOfferAnswer) {
+  auto caller = CreatePeerConnectionWithAudioVideo();
+  auto callee = CreatePeerConnection();
+
+  EXPECT_FALSE(HasDtlsTransport(caller));
+  EXPECT_FALSE(HasDtlsTransport(callee));
+  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
+  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
+  EXPECT_TRUE(HasDtlsTransport(caller));
+  callee->SetRemoteDescription(std::move(offer));
+  EXPECT_FALSE(HasDtlsTransport(callee));
+  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
+  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
+  EXPECT_TRUE(HasDtlsTransport(callee));
+  caller->SetRemoteDescription(std::move(answer));
+  EXPECT_TRUE(HasDtlsTransport(caller));
+
+  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
+}
+
+TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
+  auto caller = CreatePeerConnectionWithAudioVideo();
+  auto callee = CreatePeerConnection();
+
+  EXPECT_FALSE(HasDtlsTransport(caller));
+  EXPECT_FALSE(HasDtlsTransport(callee));
+  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
+  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
+  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
+  callee->SetRemoteDescription(std::move(offer));
+  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
+  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
+  caller->SetRemoteDescription(std::move(answer));
+  EXPECT_EQ(1, NumberOfDtlsTransports(caller));
+
+  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
+}
+
+TEST_F(PeerConnectionSignalingUnifiedPlanTest,
+       DtlsTransportsAreSeparateeWhenUnbundled) {
+  auto caller = CreatePeerConnectionWithAudioVideo();
+  auto callee = CreatePeerConnection();
+
+  EXPECT_FALSE(HasDtlsTransport(caller));
+  EXPECT_FALSE(HasDtlsTransport(callee));
+  RTCOfferAnswerOptions unbundle_options;
+  unbundle_options.use_rtp_mux = false;
+  auto offer = caller->CreateOffer(unbundle_options);
+  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
+  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
+  callee->SetRemoteDescription(std::move(offer));
+  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
+  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
+  EXPECT_EQ(2, NumberOfDtlsTransports(callee));
+  caller->SetRemoteDescription(std::move(answer));
+  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
+
+  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
+}
+
 }  // namespace webrtc
diff --git a/pc/rtp_receiver.h b/pc/rtp_receiver.h
index 754fce0..86673e8 100644
--- a/pc/rtp_receiver.h
+++ b/pc/rtp_receiver.h
@@ -54,6 +54,8 @@
   // receive packets on unsignaled SSRCs.
   virtual void SetupMediaChannel(uint32_t ssrc) = 0;
 
+  virtual void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) = 0;
   // This SSRC is used as an identifier for the receiver between the API layer
   // and the WebRtcVideoEngine, WebRtcVoiceEngine layer.
   virtual uint32_t ssrc() const = 0;
@@ -106,6 +108,9 @@
   rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
     return track_.get();
   }
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const override {
+    return dtls_transport_;
+  }
   std::vector<std::string> stream_ids() const override;
   std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams()
       const override {
@@ -133,6 +138,10 @@
   uint32_t ssrc() const override { return ssrc_.value_or(0); }
   void NotifyFirstPacketReceived() override;
   void set_stream_ids(std::vector<std::string> stream_ids) override;
+  void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) override {
+    dtls_transport_ = dtls_transport;
+  }
   void SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
                       streams) override;
   void SetObserver(RtpReceiverObserverInterface* observer) override;
@@ -160,6 +169,7 @@
   bool received_first_packet_ = false;
   int attachment_id_ = 0;
   rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
 };
 
 class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
@@ -186,6 +196,9 @@
   rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
     return track_.get();
   }
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const override {
+    return dtls_transport_;
+  }
   std::vector<std::string> stream_ids() const override;
   std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams()
       const override {
@@ -213,6 +226,10 @@
   uint32_t ssrc() const override { return ssrc_.value_or(0); }
   void NotifyFirstPacketReceived() override;
   void set_stream_ids(std::vector<std::string> stream_ids) override;
+  void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) override {
+    dtls_transport_ = dtls_transport;
+  }
   void SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
                       streams) override;
 
@@ -257,6 +274,7 @@
   bool received_first_packet_ = false;
   int attachment_id_ = 0;
   rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
 };
 
 }  // namespace webrtc
diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h
index 6ed0603..fd8980c 100644
--- a/pc/rtp_sender.h
+++ b/pc/rtp_sender.h
@@ -50,6 +50,8 @@
   virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0;
   virtual void set_init_send_encodings(
       const std::vector<RtpEncodingParameters>& init_send_encodings) = 0;
+  virtual void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) = 0;
 
   virtual void Stop() = 0;
 
@@ -112,6 +114,10 @@
     return track_;
   }
 
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const override {
+    return dtls_transport_;
+  }
+
   uint32_t ssrc() const override { return ssrc_; }
 
   cricket::MediaType media_type() const override {
@@ -147,7 +153,10 @@
   std::vector<RtpEncodingParameters> init_send_encodings() const override {
     return init_parameters_.encodings;
   }
-
+  void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) override {
+    dtls_transport_ = dtls_transport;
+  }
   void Stop() override;
 
   int AttachmentId() const override { return attachment_id_; }
@@ -173,6 +182,7 @@
   cricket::VoiceMediaChannel* media_channel_ = nullptr;
   StatsCollector* stats_ = nullptr;
   rtc::scoped_refptr<AudioTrackInterface> track_;
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
   rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender_proxy_;
   absl::optional<std::string> last_transaction_id_;
   uint32_t ssrc_ = 0;
@@ -205,6 +215,9 @@
   }
 
   uint32_t ssrc() const override { return ssrc_; }
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const override {
+    return dtls_transport_;
+  }
 
   cricket::MediaType media_type() const override {
     return cricket::MEDIA_TYPE_VIDEO;
@@ -221,6 +234,10 @@
   std::vector<RtpEncodingParameters> init_send_encodings() const override {
     return init_parameters_.encodings;
   }
+  void set_transport(
+      rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) override {
+    dtls_transport_ = dtls_transport;
+  }
 
   RtpParameters GetParameters() override;
   RTCError SetParameters(const RtpParameters& parameters) override;
@@ -266,6 +283,7 @@
   bool stopped_ = false;
   int attachment_id_ = 0;
   rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_;
+  rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
 };
 
 }  // namespace webrtc
diff --git a/pc/test/mock_rtp_receiver_internal.h b/pc/test/mock_rtp_receiver_internal.h
index 10807da..f948d83 100644
--- a/pc/test/mock_rtp_receiver_internal.h
+++ b/pc/test/mock_rtp_receiver_internal.h
@@ -25,6 +25,8 @@
   // RtpReceiverInterface methods.
   MOCK_METHOD1(SetTrack, void(MediaStreamTrackInterface*));
   MOCK_CONST_METHOD0(track, rtc::scoped_refptr<MediaStreamTrackInterface>());
+  MOCK_CONST_METHOD0(dtls_transport,
+                     rtc::scoped_refptr<DtlsTransportInterface>());
   MOCK_CONST_METHOD0(stream_ids, std::vector<std::string>());
   MOCK_CONST_METHOD0(streams,
                      std::vector<rtc::scoped_refptr<MediaStreamInterface>>());
@@ -46,6 +48,7 @@
   MOCK_CONST_METHOD0(ssrc, uint32_t());
   MOCK_METHOD0(NotifyFirstPacketReceived, void());
   MOCK_METHOD1(set_stream_ids, void(std::vector<std::string>));
+  MOCK_METHOD1(set_transport, void(rtc::scoped_refptr<DtlsTransportInterface>));
   MOCK_METHOD1(
       SetStreams,
       void(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&));
diff --git a/pc/test/mock_rtp_sender_internal.h b/pc/test/mock_rtp_sender_internal.h
index 7859175..fff81f4 100644
--- a/pc/test/mock_rtp_sender_internal.h
+++ b/pc/test/mock_rtp_sender_internal.h
@@ -26,10 +26,13 @@
   MOCK_METHOD1(SetTrack, bool(MediaStreamTrackInterface*));
   MOCK_CONST_METHOD0(track, rtc::scoped_refptr<MediaStreamTrackInterface>());
   MOCK_CONST_METHOD0(ssrc, uint32_t());
+  MOCK_CONST_METHOD0(dtls_transport,
+                     rtc::scoped_refptr<DtlsTransportInterface>());
   MOCK_CONST_METHOD0(media_type, cricket::MediaType());
   MOCK_CONST_METHOD0(id, std::string());
   MOCK_CONST_METHOD0(stream_ids, std::vector<std::string>());
   MOCK_CONST_METHOD0(init_send_encodings, std::vector<RtpEncodingParameters>());
+  MOCK_METHOD1(set_transport, void(rtc::scoped_refptr<DtlsTransportInterface>));
   MOCK_METHOD0(GetParameters, RtpParameters());
   MOCK_METHOD1(SetParameters, RTCError(const RtpParameters&));
   MOCK_CONST_METHOD0(GetDtmfSender, rtc::scoped_refptr<DtmfSenderInterface>());