1 /*
2 * Copyright 2021 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "pc/audio_rtp_receiver.h"
12
13 #include <atomic>
14
15 #include "pc/test/mock_voice_media_channel.h"
16 #include "rtc_base/gunit.h"
17 #include "rtc_base/thread.h"
18 #include "test/gmock.h"
19 #include "test/gtest.h"
20 #include "test/run_loop.h"
21
22 using ::testing::_;
23 using ::testing::InvokeWithoutArgs;
24 using ::testing::Mock;
25
26 static const int kTimeOut = 100;
27 static const double kDefaultVolume = 1;
28 static const double kVolume = 3.7;
29 static const double kVolumeMuted = 0.0;
30 static const uint32_t kSsrc = 3;
31
32 namespace webrtc {
33 class AudioRtpReceiverTest : public ::testing::Test {
34 protected:
AudioRtpReceiverTest()35 AudioRtpReceiverTest()
36 : worker_(rtc::Thread::Current()),
37 receiver_(
38 rtc::make_ref_counted<AudioRtpReceiver>(worker_,
39 std::string(),
40 std::vector<std::string>(),
41 false)),
42 media_channel_(rtc::Thread::Current()) {
43 EXPECT_CALL(media_channel_, SetRawAudioSink(kSsrc, _));
44 EXPECT_CALL(media_channel_, SetBaseMinimumPlayoutDelayMs(kSsrc, _));
45 }
46
~AudioRtpReceiverTest()47 ~AudioRtpReceiverTest() {
48 EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolumeMuted));
49 receiver_->SetMediaChannel(nullptr);
50 }
51
52 rtc::AutoThread main_thread_;
53 rtc::Thread* worker_;
54 rtc::scoped_refptr<AudioRtpReceiver> receiver_;
55 cricket::MockVoiceMediaChannel media_channel_;
56 };
57
TEST_F(AudioRtpReceiverTest,SetOutputVolumeIsCalled)58 TEST_F(AudioRtpReceiverTest, SetOutputVolumeIsCalled) {
59 std::atomic_int set_volume_calls(0);
60
61 EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kDefaultVolume))
62 .WillOnce(InvokeWithoutArgs([&] {
63 set_volume_calls++;
64 return true;
65 }));
66
67 receiver_->track();
68 receiver_->track()->set_enabled(true);
69 receiver_->SetMediaChannel(&media_channel_);
70 EXPECT_CALL(media_channel_, SetDefaultRawAudioSink(_)).Times(0);
71 receiver_->SetupMediaChannel(kSsrc);
72
73 EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume))
74 .WillOnce(InvokeWithoutArgs([&] {
75 set_volume_calls++;
76 return true;
77 }));
78
79 receiver_->OnSetVolume(kVolume);
80 EXPECT_TRUE_WAIT(set_volume_calls == 2, kTimeOut);
81 }
82
TEST_F(AudioRtpReceiverTest,VolumesSetBeforeStartingAreRespected)83 TEST_F(AudioRtpReceiverTest, VolumesSetBeforeStartingAreRespected) {
84 // Set the volume before setting the media channel. It should still be used
85 // as the initial volume.
86 receiver_->OnSetVolume(kVolume);
87
88 receiver_->track()->set_enabled(true);
89 receiver_->SetMediaChannel(&media_channel_);
90
91 // The previosly set initial volume should be propagated to the provided
92 // media_channel_ as soon as SetupMediaChannel is called.
93 EXPECT_CALL(media_channel_, SetOutputVolume(kSsrc, kVolume));
94
95 receiver_->SetupMediaChannel(kSsrc);
96 }
97
98 // Tests that OnChanged notifications are processed correctly on the worker
99 // thread when a media channel pointer is passed to the receiver via the
100 // constructor.
TEST(AudioRtpReceiver,OnChangedNotificationsAfterConstruction)101 TEST(AudioRtpReceiver, OnChangedNotificationsAfterConstruction) {
102 webrtc::test::RunLoop loop;
103 auto* thread = rtc::Thread::Current(); // Points to loop's thread.
104 cricket::MockVoiceMediaChannel media_channel(thread);
105 auto receiver = rtc::make_ref_counted<AudioRtpReceiver>(
106 thread, std::string(), std::vector<std::string>(), true, &media_channel);
107
108 EXPECT_CALL(media_channel, SetDefaultRawAudioSink(_)).Times(1);
109 EXPECT_CALL(media_channel, SetDefaultOutputVolume(kDefaultVolume)).Times(1);
110 receiver->SetupUnsignaledMediaChannel();
111 loop.Flush();
112
113 // Mark the track as disabled.
114 receiver->track()->set_enabled(false);
115
116 // When the track was marked as disabled, an async notification was queued
117 // for the worker thread. This notification should trigger the volume
118 // of the media channel to be set to kVolumeMuted.
119 // Flush the worker thread, but set the expectation first for the call.
120 EXPECT_CALL(media_channel, SetDefaultOutputVolume(kVolumeMuted)).Times(1);
121 loop.Flush();
122
123 EXPECT_CALL(media_channel, SetDefaultOutputVolume(kVolumeMuted)).Times(1);
124 receiver->SetMediaChannel(nullptr);
125 }
126
127 } // namespace webrtc
128