Add callback for send codec in audio too

It turns out there's a similar linkage as the one for video.
Tests are coming in https://webrtc-review.googlesource.com/c/src/+/307461

Bug: webrtc:13931
Change-Id: I638d1a1907116a71481aa88dce932492323ae5b7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307463
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40206}
diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h
index b00de20..74128cb 100644
--- a/media/base/fake_media_engine.h
+++ b/media/base/fake_media_engine.h
@@ -420,6 +420,9 @@
   bool SenderNonSenderRttEnabled() const override { return false; }
   void SetReceiveNackEnabled(bool enabled) {}
   void SetReceiveNonSenderRttEnabled(bool enabled) {}
+  bool SendCodecHasNack() const override { return false; }
+  void SetSendCodecChangedCallback(
+      absl::AnyInvocable<void()> callback) override {}
 
  private:
   class VoiceChannelAudioSink : public AudioSource::Sink {
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index 9749cd0..e982284 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -247,9 +247,14 @@
       webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
   }
   virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0;
+  virtual bool SendCodecHasNack() const = 0;
   // Called whenever the list of sending SSRCs changes.
   virtual void SetSsrcListChangedCallback(
       absl::AnyInvocable<void(const std::set<uint32_t>&)> callback) = 0;
+  // TODO(bugs.webrtc.org/13931): Remove when configuration is more sensible
+  virtual void SetSendCodecChangedCallback(
+      absl::AnyInvocable<void()> callback) = 0;
+
   // Get the underlying send/receive implementation channel for testing.
   // TODO(bugs.webrtc.org/13931): Remove method and the fakes that depend on it.
   virtual MediaChannel* ImplForTesting() = 0;
@@ -952,11 +957,7 @@
   // Information queries to support SetReceiverFeedbackParameters
   virtual webrtc::RtcpMode SendCodecRtcpMode() const = 0;
   virtual bool SendCodecHasLntf() const = 0;
-  virtual bool SendCodecHasNack() const = 0;
   virtual absl::optional<int> SendCodecRtxTime() const = 0;
-  // TODO(bugs.webrtc.org/13931): Remove when configuration is more sensible
-  virtual void SetSendCodecChangedCallback(
-      absl::AnyInvocable<void()> callback) = 0;
 };
 
 class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface {
diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h
index dfd9fb3..d4d8182 100644
--- a/media/base/media_channel_impl.h
+++ b/media/base/media_channel_impl.h
@@ -206,6 +206,8 @@
   void OnNetworkRouteChanged(absl::string_view transport_name,
                              const rtc::NetworkRoute& network_route) override =
       0;
+  void SetSendCodecChangedCallback(
+      absl::AnyInvocable<void()> callback) override = 0;
 
   // Methods from the APIs that are implemented in MediaChannelUtil
   using MediaChannelUtil::ExtmapAllowMixed;
@@ -469,6 +471,11 @@
   bool SenderNonSenderRttEnabled() const override {
     return impl_->SenderNonSenderRttEnabled();
   }
+  bool SendCodecHasNack() const override { return impl()->SendCodecHasNack(); }
+  void SetSendCodecChangedCallback(
+      absl::AnyInvocable<void()> callback) override {
+    impl()->SetSendCodecChangedCallback(std::move(callback));
+  }
   MediaChannel* ImplForTesting() override { return impl_; }
 
  private:
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index a763ddb..1b240d6 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -1761,15 +1761,17 @@
   }
   call_->GetTransportControllerSend()->SetSdpBitrateParameters(bitrate_config);
 
+  send_codecs_ = codecs;
   // In legacy kBoth mode, the MediaChannel sets the NACK status.
   // In other modes, this is done externally.
 
   if (role() == MediaChannel::Role::kBoth) {
     SetReceiveNackEnabled(send_codec_spec_->nack_enabled);
     SetReceiveNonSenderRttEnabled(send_codec_spec_->enable_non_sender_rtt);
+  } else if (send_codec_changed_callback_) {
+    send_codec_changed_callback_();
   }
 
-  send_codecs_ = codecs;
   return true;
 }
 
diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h
index e73c24c..474acc4 100644
--- a/media/engine/webrtc_voice_engine.h
+++ b/media/engine/webrtc_voice_engine.h
@@ -18,6 +18,7 @@
 #include <memory>
 #include <set>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
@@ -304,9 +305,14 @@
     }
     return send_codec_spec_->enable_non_sender_rtt;
   }
+  bool SendCodecHasNack() const override { return SenderNackEnabled(); }
 
   void SetReceiveNackEnabled(bool enabled) override;
   void SetReceiveNonSenderRttEnabled(bool enabled) override;
+  void SetSendCodecChangedCallback(
+      absl::AnyInvocable<void()> callback) override {
+    send_codec_changed_callback_ = std::move(callback);
+  }
 
  private:
   bool SetOptions(const AudioOptions& options);
@@ -404,6 +410,9 @@
   void FillSendCodecStats(VoiceMediaSendInfo* voice_media_info);
   void FillReceiveCodecStats(VoiceMediaReceiveInfo* voice_media_info);
 
+  // Callback invoked whenever the send codec changes.
+  // TODO(bugs.webrtc.org/13931): Remove again when coupling isn't needed.
+  absl::AnyInvocable<void()> send_codec_changed_callback_;
   // Callback invoked whenever the list of SSRCs changes.
   absl::AnyInvocable<void(const std::set<uint32_t>&)>
       ssrc_list_changed_callback_;
diff --git a/pc/channel.cc b/pc/channel.cc
index bf98278..f9ee3ff 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -886,7 +886,9 @@
                   crypto_options,
                   ssrc_generator),
       send_channel_(media_channel_impl_->AsVoiceChannel()),
-      receive_channel_(media_channel_impl_->AsVoiceChannel()) {}
+      receive_channel_(media_channel_impl_->AsVoiceChannel()) {
+  InitCallback();
+}
 
 VoiceChannel::~VoiceChannel() {
   TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
@@ -894,6 +896,18 @@
   DisableMedia_w();
 }
 
+void VoiceChannel::InitCallback() {
+  RTC_DCHECK_RUN_ON(worker_thread());
+  // TODO(bugs.webrtc.org/13931): Remove when values are set
+  // in a more sensible fashion
+  send_channel_.SetSendCodecChangedCallback([this]() {
+    RTC_DCHECK_RUN_ON(worker_thread());
+    // Adjust receive streams based on send codec.
+    receive_channel_.SetReceiveNackEnabled(send_channel_.SendCodecHasNack());
+    receive_channel_.SetReceiveNonSenderRttEnabled(
+        send_channel_.SenderNonSenderRttEnabled());
+  });
+}
 void VoiceChannel::UpdateMediaSendRecvState_w() {
   // Render incoming data if we're the active call, and we have the local
   // content. We receive data on the default channel and multiplexed streams.
diff --git a/pc/channel.h b/pc/channel.h
index a84a842..89af890 100644
--- a/pc/channel.h
+++ b/pc/channel.h
@@ -435,6 +435,7 @@
   }
 
  private:
+  void InitCallback();
   // overrides from BaseChannel
   void UpdateMediaSendRecvState_w() RTC_RUN_ON(worker_thread()) override;
   bool SetLocalContent_w(const MediaContentDescription* content,
diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h
index 8748532..e3eb42d 100644
--- a/pc/test/mock_voice_media_channel.h
+++ b/pc/test/mock_voice_media_channel.h
@@ -67,10 +67,15 @@
               ChooseReceiverReportSsrc,
               (const std::set<uint32_t>&),
               (override));
+  MOCK_METHOD(bool, SendCodecHasNack, (), (const, override));
   MOCK_METHOD(void,
               SetSsrcListChangedCallback,
               (absl::AnyInvocable<void(const std::set<uint32_t>&)>),
               (override));
+  MOCK_METHOD(void,
+              SetSendCodecChangedCallback,
+              (absl::AnyInvocable<void()>),
+              (override));
   MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override));
   MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override));
   MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const, override));