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