Add unit test of AudioRtpReceiver

Bug: chromium:1272566
Change-Id: Ic10c586062cc8fdded2dd6249b49fab527c99823
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/238987
Commit-Queue: Tony Herre <toprice@chromium.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35429}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index f31109a..f29b558 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -874,6 +874,7 @@
     testonly = true
 
     sources = [
+      "audio_rtp_receiver_unittest.cc",
       "channel_manager_unittest.cc",
       "channel_unittest.cc",
       "dtls_srtp_transport_unittest.cc",
@@ -902,6 +903,7 @@
     }
 
     deps = [
+      ":audio_rtp_receiver",
       ":libjingle_peerconnection",
       ":pc_test_utils",
       ":peerconnection",
@@ -939,6 +941,7 @@
       "../rtc_base/third_party/sigslot",
       "../system_wrappers:metrics",
       "../test:field_trial",
+      "../test:test_common",
       "../test:test_main",
       "../test:test_support",
       "//third_party/abseil-cpp/absl/algorithm:container",
@@ -1345,6 +1348,7 @@
       "test/mock_peer_connection_observers.h",
       "test/mock_rtp_receiver_internal.h",
       "test/mock_rtp_sender_internal.h",
+      "test/mock_voice_media_channel.h",
       "test/peer_connection_test_wrapper.cc",
       "test/peer_connection_test_wrapper.h",
       "test/rtc_stats_obtainer.h",
diff --git a/pc/audio_rtp_receiver.cc b/pc/audio_rtp_receiver.cc
index cfaee40..7890d9b 100644
--- a/pc/audio_rtp_receiver.cc
+++ b/pc/audio_rtp_receiver.cc
@@ -167,8 +167,10 @@
 
   worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
     RTC_DCHECK_RUN_ON(worker_thread_);
+
     if (media_channel_)
       SetOutputVolume_w(0.0);
+
     SetMediaChannel_w(nullptr);
   });
 }
diff --git a/pc/audio_rtp_receiver_unittest.cc b/pc/audio_rtp_receiver_unittest.cc
new file mode 100644
index 0000000..1865115
--- /dev/null
+++ b/pc/audio_rtp_receiver_unittest.cc
@@ -0,0 +1,92 @@
+/*
+ *  Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "pc/audio_rtp_receiver.h"
+
+#include "media/base/media_channel.h"
+#include "pc/test/mock_voice_media_channel.h"
+#include "rtc_base/gunit.h"
+#include "rtc_base/thread.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::_;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Mock;
+
+static const int kTimeOut = 100;
+static const double kDefaultVolume = 1;
+static const double kVolume = 3.7;
+static const uint32_t kSsrc = 3;
+
+namespace webrtc {
+class AudioRtpReceiverTest : public ::testing::Test {
+ protected:
+  AudioRtpReceiverTest()
+      : worker_(rtc::Thread::Current()),
+        receiver_(
+            rtc::make_ref_counted<AudioRtpReceiver>(worker_,
+                                                    std::string(),
+                                                    std::vector<std::string>(),
+                                                    false)),
+        media_channel_(rtc::Thread::Current()) {
+    EXPECT_CALL(media_channel_, SetRawAudioSink(kSsrc, _));
+    EXPECT_CALL(media_channel_, SetBaseMinimumPlayoutDelayMs(kSsrc, _));
+  }
+
+  ~AudioRtpReceiverTest() {
+    receiver_->SetMediaChannel(nullptr);
+    receiver_->Stop();
+  }
+
+  rtc::Thread* worker_;
+  rtc::scoped_refptr<AudioRtpReceiver> receiver_;
+  cricket::MockVoiceMediaChannel media_channel_;
+};
+
+TEST_F(AudioRtpReceiverTest, SetOutputVolumeIsCalled) {
+  std::atomic_int set_volume_calls(0);
+
+  EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kDefaultVolume))
+      .WillOnce(InvokeWithoutArgs([&] {
+        set_volume_calls++;
+        return true;
+      }));
+
+  receiver_->track();
+  receiver_->track()->set_enabled(true);
+  receiver_->SetMediaChannel(&media_channel_);
+  receiver_->SetupMediaChannel(kSsrc);
+
+  EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume))
+      .WillOnce(InvokeWithoutArgs([&] {
+        set_volume_calls++;
+        return true;
+      }));
+
+  receiver_->OnSetVolume(kVolume);
+  EXPECT_TRUE_WAIT(set_volume_calls == 2, kTimeOut);
+}
+
+TEST_F(AudioRtpReceiverTest, VolumesSetBeforeStartingAreRespected) {
+  // Set the volume before setting the media channel. It should still be used
+  // as the initial volume.
+  receiver_->OnSetVolume(kVolume);
+
+  receiver_->track()->set_enabled(true);
+  receiver_->SetMediaChannel(&media_channel_);
+
+  // The previosly set initial volume should be propagated to the provided
+  // media_channel_ as soon as SetupMediaChannel is called.
+  EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume));
+
+  receiver_->SetupMediaChannel(kSsrc);
+}
+}  // namespace webrtc
diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h
new file mode 100644
index 0000000..d6756b1
--- /dev/null
+++ b/pc/test/mock_voice_media_channel.h
@@ -0,0 +1,151 @@
+/*
+ *  Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_
+#define PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "media/base/media_channel.h"
+#include "rtc_base/gunit.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::InvokeWithoutArgs;
+using ::testing::Mock;
+
+namespace cricket {
+class MockVoiceMediaChannel : public VoiceMediaChannel {
+ public:
+  explicit MockVoiceMediaChannel(webrtc::TaskQueueBase* network_thread)
+      : VoiceMediaChannel(network_thread) {}
+
+  MOCK_METHOD(void, SetInterface, (NetworkInterface * iface), (override));
+  MOCK_METHOD(void,
+              OnPacketReceived,
+              (rtc::CopyOnWriteBuffer packet, int64_t packet_time_us),
+              (override));
+  MOCK_METHOD(void,
+              OnPacketSent,
+              (const rtc::SentPacket& sent_packet),
+              (override));
+  MOCK_METHOD(void, OnReadyToSend, (bool ready), (override));
+  MOCK_METHOD(void,
+              OnNetworkRouteChanged,
+              (const std::string& transport_name,
+               const rtc::NetworkRoute& network_route),
+              (override));
+  MOCK_METHOD(bool, AddSendStream, (const StreamParams& sp), (override));
+  MOCK_METHOD(bool, RemoveSendStream, (uint32_t ssrc), (override));
+  MOCK_METHOD(bool, AddRecvStream, (const StreamParams& sp), (override));
+  MOCK_METHOD(bool, RemoveRecvStream, (uint32_t ssrc), (override));
+  MOCK_METHOD(void, ResetUnsignaledRecvStream, (), (override));
+  MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override));
+  MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override));
+  MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const override));
+  MOCK_METHOD(
+      void,
+      SetFrameEncryptor,
+      (uint32_t ssrc,
+       rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor),
+      (override));
+  MOCK_METHOD(
+      void,
+      SetFrameDecryptor,
+      (uint32_t ssrc,
+       rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor),
+      (override));
+  MOCK_METHOD(void, SetVideoCodecSwitchingEnabled, (bool enabled), (override));
+  MOCK_METHOD(webrtc::RtpParameters,
+              GetRtpSendParameters,
+              (uint32_t ssrc),
+              (const override));
+  MOCK_METHOD(webrtc::RTCError,
+              SetRtpSendParameters,
+              (uint32_t ssrc, const webrtc::RtpParameters& parameters),
+              (override));
+  MOCK_METHOD(
+      void,
+      SetEncoderToPacketizerFrameTransformer,
+      (uint32_t ssrc,
+       rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
+      (override));
+  MOCK_METHOD(
+      void,
+      SetDepacketizerToDecoderFrameTransformer,
+      (uint32_t ssrc,
+       rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
+      (override));
+
+  MOCK_METHOD(bool,
+              SetSendParameters,
+              (const AudioSendParameters& params),
+              (override));
+  MOCK_METHOD(bool,
+              SetRecvParameters,
+              (const AudioRecvParameters& params),
+              (override));
+  MOCK_METHOD(webrtc::RtpParameters,
+              GetRtpReceiveParameters,
+              (uint32_t ssrc),
+              (const override));
+  MOCK_METHOD(webrtc::RtpParameters,
+              GetDefaultRtpReceiveParameters,
+              (),
+              (const override));
+  MOCK_METHOD(void, SetPlayout, (bool playout), (override));
+  MOCK_METHOD(void, SetSend, (bool send), (override));
+  MOCK_METHOD(bool,
+              SetAudioSend,
+              (uint32_t ssrc,
+               bool enable,
+               const AudioOptions* options,
+               AudioSource* source),
+              (override));
+  MOCK_METHOD(bool,
+              SetOutputVolume,
+              (uint32_t ssrc, double volume),
+              (override));
+  MOCK_METHOD(bool, SetDefaultOutputVolume, (double volume), (override));
+  MOCK_METHOD(bool, CanInsertDtmf, (), (override));
+  MOCK_METHOD(bool,
+              InsertDtmf,
+              (uint32_t ssrc, int event, int duration),
+              (override));
+  MOCK_METHOD(bool,
+              GetStats,
+              (VoiceMediaInfo * info, bool get_and_clear_legacy_stats),
+              (override));
+  MOCK_METHOD(void,
+              SetRawAudioSink,
+              (uint32_t ssrc, std::unique_ptr<webrtc::AudioSinkInterface> sink),
+              (override));
+  MOCK_METHOD(void,
+              SetDefaultRawAudioSink,
+              (std::unique_ptr<webrtc::AudioSinkInterface> sink),
+              (override));
+  MOCK_METHOD(std::vector<webrtc::RtpSource>,
+              GetSources,
+              (uint32_t ssrc),
+              (const override));
+
+  MOCK_METHOD(bool,
+              SetBaseMinimumPlayoutDelayMs,
+              (uint32_t ssrc, int delay_ms),
+              (override));
+  MOCK_METHOD(absl::optional<int>,
+              GetBaseMinimumPlayoutDelayMs,
+              (uint32_t ssrc),
+              (const override));
+};
+}  // namespace cricket
+
+#endif  // PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_