Add AudioSendStream::SetMuted() method and use it in WVoMC::MuteStream().

Removes the need to use VoEVolume::SetInputMute()/GetInputMute().

BUG=webrtc:4690
NOTRY=true

Review-Url: https://codereview.webrtc.org/2066973002
Cr-Commit-Position: refs/heads/master@{#13172}
diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc
index 9aa2fc0..d08bfea 100644
--- a/webrtc/audio/audio_send_stream.cc
+++ b/webrtc/audio/audio_send_stream.cc
@@ -127,6 +127,11 @@
          channel_proxy_->SendTelephoneEventOutband(event, duration_ms);
 }
 
+void AudioSendStream::SetMuted(bool muted) {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  channel_proxy_->SetInputMute(muted);
+}
+
 webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   webrtc::AudioSendStream::Stats stats;
diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h
index 61dd7f2..264f9b3 100644
--- a/webrtc/audio/audio_send_stream.h
+++ b/webrtc/audio/audio_send_stream.h
@@ -39,6 +39,7 @@
   void Stop() override;
   bool SendTelephoneEvent(int payload_type, int event,
                           int duration_ms) override;
+  void SetMuted(bool muted) override;
   webrtc::AudioSendStream::Stats GetStats() const override;
 
   void SignalNetworkState(NetworkState state);
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index 44392ea..b953554 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -110,6 +110,7 @@
 
   AudioSendStream::Config& config() { return stream_config_; }
   rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
+  MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
   CongestionController* congestion_controller() {
     return &congestion_controller_;
   }
@@ -200,6 +201,14 @@
       kTelephoneEventCode, kTelephoneEventDuration));
 }
 
+TEST(AudioSendStreamTest, SetMuted) {
+  ConfigHelper helper;
+  internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
+                                        helper.congestion_controller());
+  EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true));
+  send_stream.SetMuted(true);
+}
+
 TEST(AudioSendStreamTest, GetStats) {
   ConfigHelper helper;
   internal::AudioSendStream send_stream(helper.config(), helper.audio_state(),
diff --git a/webrtc/audio_send_stream.h b/webrtc/audio_send_stream.h
index ffb5f9c..1c6803c 100644
--- a/webrtc/audio_send_stream.h
+++ b/webrtc/audio_send_stream.h
@@ -100,6 +100,9 @@
   // TODO(solenberg): Make payload_type a config property instead.
   virtual bool SendTelephoneEvent(int payload_type, int event,
                                   int duration_ms) = 0;
+
+  virtual void SetMuted(bool muted) = 0;
+
   virtual Stats GetStats() const = 0;
 
  protected:
diff --git a/webrtc/media/engine/fakewebrtccall.cc b/webrtc/media/engine/fakewebrtccall.cc
index edb2fa4..fd020d4 100644
--- a/webrtc/media/engine/fakewebrtccall.cc
+++ b/webrtc/media/engine/fakewebrtccall.cc
@@ -47,6 +47,10 @@
   return true;
 }
 
+void FakeAudioSendStream::SetMuted(bool muted) {
+  muted_ = muted;
+}
+
 webrtc::AudioSendStream::Stats FakeAudioSendStream::GetStats() const {
   return stats_;
 }
diff --git a/webrtc/media/engine/fakewebrtccall.h b/webrtc/media/engine/fakewebrtccall.h
index 2d1cb74..4a0e41c 100644
--- a/webrtc/media/engine/fakewebrtccall.h
+++ b/webrtc/media/engine/fakewebrtccall.h
@@ -46,6 +46,7 @@
   void SetStats(const webrtc::AudioSendStream::Stats& stats);
   TelephoneEvent GetLatestTelephoneEvent() const;
   bool IsSending() const { return sending_; }
+  bool muted() const { return muted_; }
 
  private:
   // webrtc::AudioSendStream implementation.
@@ -54,12 +55,14 @@
 
   bool SendTelephoneEvent(int payload_type, int event,
                           int duration_ms) override;
+  void SetMuted(bool muted) override;
   webrtc::AudioSendStream::Stats GetStats() const override;
 
   TelephoneEvent latest_telephone_event_;
   webrtc::AudioSendStream::Config config_;
   webrtc::AudioSendStream::Stats stats_;
   bool sending_ = false;
+  bool muted_ = false;
 };
 
 class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
diff --git a/webrtc/media/engine/webrtcvoe.h b/webrtc/media/engine/webrtcvoe.h
index 238b4ce..cbb6863 100644
--- a/webrtc/media/engine/webrtcvoe.h
+++ b/webrtc/media/engine/webrtcvoe.h
@@ -23,7 +23,6 @@
 #include "webrtc/voice_engine/include/voe_codec.h"
 #include "webrtc/voice_engine/include/voe_errors.h"
 #include "webrtc/voice_engine/include/voe_hardware.h"
-#include "webrtc/voice_engine/include/voe_network.h"
 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
 #include "webrtc/voice_engine/include/voe_volume_control.h"
 
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc
index b2eda0e..c1084c3 100644
--- a/webrtc/media/engine/webrtcvoiceengine.cc
+++ b/webrtc/media/engine/webrtcvoiceengine.cc
@@ -1145,6 +1145,18 @@
     UpdateSendState();
   }
 
+  void SetMuted(bool muted) {
+    RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+    RTC_DCHECK(stream_);
+    stream_->SetMuted(muted);
+    muted_ = muted;
+  }
+
+  bool muted() const {
+    RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+    return muted_;
+  }
+
   webrtc::AudioSendStream::Stats GetStats() const {
     RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
     RTC_DCHECK(stream_);
@@ -1250,6 +1262,7 @@
   // goes away.
   AudioSource* source_ = nullptr;
   bool send_ = false;
+  bool muted_ = false;
   webrtc::RtpParameters rtp_parameters_;
 
   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
@@ -2361,29 +2374,21 @@
 
 bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  int channel = GetSendChannelId(ssrc);
-  if (channel == -1) {
+  const auto it = send_streams_.find(ssrc);
+  if (it == send_streams_.end()) {
     LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use.";
     return false;
   }
-  if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) {
-    LOG_RTCERR2(SetInputMute, channel, muted);
-    return false;
-  }
+  it->second->SetMuted(muted);
+
+  // TODO(solenberg):
   // We set the AGC to mute state only when all the channels are muted.
   // This implementation is not ideal, instead we should signal the AGC when
   // the mic channel is muted/unmuted. We can't do it today because there
   // is no good way to know which stream is mapping to the mic channel.
   bool all_muted = muted;
-  for (const auto& ch : send_streams_) {
-    if (!all_muted) {
-      break;
-    }
-    if (engine()->voe()->volume()->GetInputMute(ch.second->channel(),
-                                                all_muted)) {
-      LOG_RTCERR1(GetInputMute, ch.second->channel());
-      return false;
-    }
+  for (const auto& kv : send_streams_) {
+    all_muted = all_muted && kv.second->muted();
   }
 
   webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing();
diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
index 98495af..7c25367 100644
--- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc
+++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
@@ -2135,6 +2135,17 @@
   EXPECT_FALSE(GetSendStream(kSsrc1).IsSending());
 }
 
+// Test that a channel is muted/unmuted.
+TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
+  EXPECT_TRUE(SetupSendStream());
+  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
+  EXPECT_FALSE(GetSendStream(kSsrc1).muted());
+  EXPECT_TRUE(channel_->SetAudioSend(kSsrc1, true, nullptr, nullptr));
+  EXPECT_FALSE(GetSendStream(kSsrc1).muted());
+  EXPECT_TRUE(channel_->SetAudioSend(kSsrc1, false, nullptr, nullptr));
+  EXPECT_TRUE(GetSendStream(kSsrc1).muted());
+}
+
 // Test that SetSendParameters() does not alter a stream's send state.
 TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
   EXPECT_TRUE(SetupSendStream());
diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h
index 8b14545..da215d6 100644
--- a/webrtc/test/mock_voe_channel_proxy.h
+++ b/webrtc/test/mock_voe_channel_proxy.h
@@ -45,6 +45,8 @@
   MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t());
   MOCK_METHOD1(SetSendTelephoneEventPayloadType, bool(int payload_type));
   MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms));
+  MOCK_METHOD1(SetInputMute, void(bool muted));
+
   MOCK_METHOD1(RegisterExternalTransport, void(Transport* transport));
   MOCK_METHOD0(DeRegisterExternalTransport, void());
   MOCK_METHOD3(ReceivedRTPPacket, bool(const uint8_t* packet,
diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc
index e148649..46288e9 100644
--- a/webrtc/voice_engine/channel_proxy.cc
+++ b/webrtc/voice_engine/channel_proxy.cc
@@ -163,6 +163,12 @@
   channel()->SetSink(std::move(sink));
 }
 
+void ChannelProxy::SetInputMute(bool muted) {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  int error = channel()->SetInputMute(muted);
+  RTC_DCHECK_EQ(0, error);
+}
+
 void ChannelProxy::RegisterExternalTransport(Transport* transport) {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   int error = channel()->RegisterExternalTransport(transport);
diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h
index 69d4f11..93b8a58 100644
--- a/webrtc/voice_engine/channel_proxy.h
+++ b/webrtc/voice_engine/channel_proxy.h
@@ -73,6 +73,7 @@
   virtual bool SetSendTelephoneEventPayloadType(int payload_type);
   virtual bool SendTelephoneEventOutband(int event, int duration_ms);
   virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink);
+  virtual void SetInputMute(bool muted);
 
   virtual void RegisterExternalTransport(Transport* transport);
   virtual void DeRegisterExternalTransport();