Adds integration of the FrameEncryptor/FrameDecryptor into the MediaChannel.

This change passes a pointer (non-owning) down to the MediaChannel when set
in the RtpSender / RtpReceiver. This currently is not used to encrypt frames.

Bug: webrtc:9681
Change-Id: I385fa8b948427803cd3f9cef918c31d7754d1b4f
Reviewed-on: https://webrtc-review.googlesource.com/97000
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Emad Omara <emadomara@webrtc.org>
Commit-Queue: Benjamin Wright <benwright@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24694}
diff --git a/media/base/mediachannel.cc b/media/base/mediachannel.cc
index 019739d..b7f1f4f 100644
--- a/media/base/mediachannel.cc
+++ b/media/base/mediachannel.cc
@@ -29,6 +29,16 @@
   return -1;
 }
 
+void MediaChannel::SetFrameEncryptor(
+    webrtc::FrameEncryptorInterface* frame_encryptor) {
+  frame_encryptor_ = frame_encryptor;
+}
+
+void MediaChannel::SetFrameDecryptor(
+    webrtc::FrameDecryptorInterface* frame_decryptor) {
+  frame_decryptor_ = frame_decryptor;
+}
+
 MediaSenderInfo::MediaSenderInfo() = default;
 MediaSenderInfo::~MediaSenderInfo() = default;
 
diff --git a/media/base/mediachannel.h b/media/base/mediachannel.h
index a4a75ed..c1cc156 100644
--- a/media/base/mediachannel.h
+++ b/media/base/mediachannel.h
@@ -20,6 +20,8 @@
 #include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_options.h"
+#include "api/crypto/framedecryptorinterface.h"
+#include "api/crypto/frameencryptorinterface.h"
 #include "api/rtcerror.h"
 #include "api/rtpparameters.h"
 #include "api/rtpreceiverinterface.h"
@@ -213,9 +215,18 @@
   // ssrc must be the first SSRC of the media stream if the stream uses
   // multiple SSRCs.
   virtual bool RemoveRecvStream(uint32_t ssrc) = 0;
-
   // Returns the absoulte sendtime extension id value from media channel.
   virtual int GetRtpSendTimeExtnId() const;
+  // Set the frame encryptor to use on all outgoing frames. This is optional.
+  // This pointers lifetime is managed by the set of RtpSender it is attached
+  // to.
+  virtual void SetFrameEncryptor(
+      webrtc::FrameEncryptorInterface* frame_encryptor);
+  // Set the frame decryptor to use on all incoming frames. This is optional.
+  // This pointers lifetimes is managed by the set of RtpReceivers it is
+  // attached to.
+  virtual void SetFrameDecryptor(
+      webrtc::FrameDecryptorInterface* frame_decryptor);
 
   // Base method to send packet using NetworkInterface.
   bool SendPacket(rtc::CopyOnWriteBuffer* packet,
@@ -266,6 +277,10 @@
   // of network_interface_ object.
   rtc::CriticalSection network_interface_crit_;
   NetworkInterface* network_interface_;
+
+ protected:
+  webrtc::FrameEncryptorInterface* frame_encryptor_ = nullptr;
+  webrtc::FrameDecryptorInterface* frame_decryptor_ = nullptr;
 };
 
 // The stats information is structured as follows:
diff --git a/pc/rtpreceiver.cc b/pc/rtpreceiver.cc
index 3d20d09..ae31f84 100644
--- a/pc/rtpreceiver.cc
+++ b/pc/rtpreceiver.cc
@@ -43,6 +43,17 @@
   return streams;
 }
 
+void AttachFrameDecryptorToMediaChannel(
+    rtc::Thread* worker_thread,
+    webrtc::FrameDecryptorInterface* frame_decryptor,
+    cricket::MediaChannel* media_channel) {
+  if (media_channel) {
+    return worker_thread->Invoke<void>(RTC_FROM_HERE, [&] {
+      media_channel->SetFrameDecryptor(frame_decryptor);
+    });
+  }
+}
+
 }  // namespace
 
 AudioRtpReceiver::AudioRtpReceiver(rtc::Thread* worker_thread,
@@ -141,6 +152,8 @@
 void AudioRtpReceiver::SetFrameDecryptor(
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
   frame_decryptor_ = std::move(frame_decryptor);
+  AttachFrameDecryptorToMediaChannel(worker_thread_, frame_decryptor_.get(),
+                                     media_channel_);
 }
 
 rtc::scoped_refptr<FrameDecryptorInterface>
@@ -243,6 +256,13 @@
   }
 }
 
+void AudioRtpReceiver::SetVoiceMediaChannel(
+    cricket::VoiceMediaChannel* voice_media_channel) {
+  media_channel_ = voice_media_channel;
+  AttachFrameDecryptorToMediaChannel(worker_thread_, frame_decryptor_.get(),
+                                     media_channel_);
+}
+
 void AudioRtpReceiver::NotifyFirstPacketReceived() {
   if (observer_) {
     observer_->OnFirstPacketReceived(media_type());
@@ -321,6 +341,8 @@
 void VideoRtpReceiver::SetFrameDecryptor(
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
   frame_decryptor_ = std::move(frame_decryptor);
+  AttachFrameDecryptorToMediaChannel(worker_thread_, frame_decryptor_.get(),
+                                     media_channel_);
 }
 
 rtc::scoped_refptr<FrameDecryptorInterface>
@@ -404,6 +426,13 @@
   }
 }
 
+void VideoRtpReceiver::SetVideoMediaChannel(
+    cricket::VideoMediaChannel* video_media_channel) {
+  media_channel_ = video_media_channel;
+  AttachFrameDecryptorToMediaChannel(worker_thread_, frame_decryptor_.get(),
+                                     media_channel_);
+}
+
 void VideoRtpReceiver::NotifyFirstPacketReceived() {
   if (observer_) {
     observer_->OnFirstPacketReceived(media_type());
diff --git a/pc/rtpreceiver.h b/pc/rtpreceiver.h
index e22e5a9..7f77d85 100644
--- a/pc/rtpreceiver.h
+++ b/pc/rtpreceiver.h
@@ -129,13 +129,10 @@
   void set_stream_ids(std::vector<std::string> stream_ids) override;
   void SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
                       streams) override;
-
   void SetObserver(RtpReceiverObserverInterface* observer) override;
-
   void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    media_channel_ = voice_media_channel;
-  }
+      cricket::VoiceMediaChannel* voice_media_channel) override;
+
   void SetVideoMediaChannel(
       cricket::VideoMediaChannel* video_media_channel) override {
     RTC_NOTREACHED();
@@ -224,10 +221,9 @@
       cricket::VoiceMediaChannel* voice_media_channel) override {
     RTC_NOTREACHED();
   }
+
   void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    media_channel_ = video_media_channel;
-  }
+      cricket::VideoMediaChannel* video_media_channel) override;
 
   int AttachmentId() const override { return attachment_id_; }
 
diff --git a/pc/rtpsender.cc b/pc/rtpsender.cc
index 2a7eca5..b7c23b8 100644
--- a/pc/rtpsender.cc
+++ b/pc/rtpsender.cc
@@ -85,6 +85,20 @@
   return false;
 }
 
+// Attaches the frame encryptor to the media channel through an invoke on a
+// worker thread. This set must be done on the corresponding worker thread that
+// the media channel was created on.
+void AttachFrameEncryptorToMediaChannel(
+    rtc::Thread* worker_thread,
+    webrtc::FrameEncryptorInterface* frame_encryptor,
+    cricket::MediaChannel* media_channel) {
+  if (media_channel) {
+    return worker_thread->Invoke<void>(RTC_FROM_HERE, [&] {
+      media_channel->SetFrameEncryptor(frame_encryptor);
+    });
+  }
+}
+
 }  // namespace
 
 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
@@ -277,6 +291,8 @@
 void AudioRtpSender::SetFrameEncryptor(
     rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
   frame_encryptor_ = std::move(frame_encryptor);
+  AttachFrameEncryptorToMediaChannel(worker_thread_, frame_encryptor_.get(),
+                                     media_channel_);
 }
 
 rtc::scoped_refptr<FrameEncryptorInterface> AudioRtpSender::GetFrameEncryptor()
@@ -325,6 +341,13 @@
   stopped_ = true;
 }
 
+void AudioRtpSender::SetVoiceMediaChannel(
+    cricket::VoiceMediaChannel* voice_media_channel) {
+  media_channel_ = voice_media_channel;
+  AttachFrameEncryptorToMediaChannel(worker_thread_, frame_encryptor_.get(),
+                                     media_channel_);
+}
+
 void AudioRtpSender::SetAudioSend() {
   RTC_DCHECK(!stopped_);
   RTC_DCHECK(can_send_track());
@@ -483,6 +506,8 @@
 void VideoRtpSender::SetFrameEncryptor(
     rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
   frame_encryptor_ = std::move(frame_encryptor);
+  AttachFrameEncryptorToMediaChannel(worker_thread_, frame_encryptor_.get(),
+                                     media_channel_);
 }
 
 rtc::scoped_refptr<FrameEncryptorInterface> VideoRtpSender::GetFrameEncryptor()
@@ -521,6 +546,13 @@
   stopped_ = true;
 }
 
+void VideoRtpSender::SetVideoMediaChannel(
+    cricket::VideoMediaChannel* video_media_channel) {
+  media_channel_ = video_media_channel;
+  AttachFrameEncryptorToMediaChannel(worker_thread_, frame_encryptor_.get(),
+                                     media_channel_);
+}
+
 void VideoRtpSender::SetVideoSend() {
   RTC_DCHECK(!stopped_);
   RTC_DCHECK(can_send_track());
diff --git a/pc/rtpsender.h b/pc/rtpsender.h
index ddef2d8..bbfaabc 100644
--- a/pc/rtpsender.h
+++ b/pc/rtpsender.h
@@ -145,9 +145,8 @@
   int AttachmentId() const override { return attachment_id_; }
 
   void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    media_channel_ = voice_media_channel;
-  }
+      cricket::VoiceMediaChannel* voice_media_channel) override;
+
   void SetVideoMediaChannel(
       cricket::VideoMediaChannel* video_media_channel) override {
     RTC_NOTREACHED();
@@ -237,10 +236,9 @@
       cricket::VoiceMediaChannel* voice_media_channel) override {
     RTC_NOTREACHED();
   }
+
   void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    media_channel_ = video_media_channel;
-  }
+      cricket::VideoMediaChannel* video_media_channel) override;
 
  private:
   bool can_send_track() const { return track_ && ssrc_; }