1 /*
2 * Copyright (c) 2020 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 "audio/voip/voip_core.h"
12 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
13 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
14 #include "api/task_queue/default_task_queue_factory.h"
15 #include "modules/audio_device/include/mock_audio_device.h"
16 #include "modules/audio_processing/include/mock_audio_processing.h"
17 #include "modules/utility/include/mock/mock_process_thread.h"
18 #include "test/gtest.h"
19 #include "test/mock_transport.h"
20
21 namespace webrtc {
22 namespace {
23
24 using ::testing::NiceMock;
25 using ::testing::Return;
26
27 constexpr int kPcmuPayload = 0;
28 constexpr int kPcmuSampleRateHz = 8000;
29 constexpr int kDtmfEventDurationMs = 1000;
30 constexpr DtmfEvent kDtmfEventCode = DtmfEvent::kDigitZero;
31
32 class VoipCoreTest : public ::testing::Test {
33 public:
34 const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};
35
VoipCoreTest()36 VoipCoreTest() { audio_device_ = test::MockAudioDeviceModule::CreateNice(); }
37
SetUp()38 void SetUp() override {
39 auto encoder_factory = CreateBuiltinAudioEncoderFactory();
40 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
41 rtc::scoped_refptr<AudioProcessing> audio_processing =
42 new rtc::RefCountedObject<test::MockAudioProcessing>();
43
44 auto process_thread = std::make_unique<NiceMock<MockProcessThread>>();
45 // Hold the pointer to use for testing.
46 process_thread_ = process_thread.get();
47
48 voip_core_ = std::make_unique<VoipCore>(
49 std::move(encoder_factory), std::move(decoder_factory),
50 CreateDefaultTaskQueueFactory(), audio_device_,
51 std::move(audio_processing), std::move(process_thread));
52 }
53
54 std::unique_ptr<VoipCore> voip_core_;
55 NiceMock<MockTransport> transport_;
56 rtc::scoped_refptr<test::MockAudioDeviceModule> audio_device_;
57 NiceMock<MockProcessThread>* process_thread_;
58 };
59
60 // Validate expected API calls that involves with VoipCore. Some verification is
61 // involved with checking mock audio device.
TEST_F(VoipCoreTest,BasicVoipCoreOperation)62 TEST_F(VoipCoreTest, BasicVoipCoreOperation) {
63 // Program mock as non-operational and ready to start.
64 EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(false));
65 EXPECT_CALL(*audio_device_, Playing()).WillOnce(Return(false));
66 EXPECT_CALL(*audio_device_, InitRecording()).WillOnce(Return(0));
67 EXPECT_CALL(*audio_device_, InitPlayout()).WillOnce(Return(0));
68 EXPECT_CALL(*audio_device_, StartRecording()).WillOnce(Return(0));
69 EXPECT_CALL(*audio_device_, StartPlayout()).WillOnce(Return(0));
70
71 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
72 EXPECT_TRUE(channel);
73
74 voip_core_->SetSendCodec(*channel, kPcmuPayload, kPcmuFormat);
75 voip_core_->SetReceiveCodecs(*channel, {{kPcmuPayload, kPcmuFormat}});
76
77 EXPECT_TRUE(voip_core_->StartSend(*channel));
78 EXPECT_TRUE(voip_core_->StartPlayout(*channel));
79
80 voip_core_->RegisterTelephoneEventType(*channel, kPcmuPayload,
81 kPcmuSampleRateHz);
82
83 EXPECT_TRUE(voip_core_->SendDtmfEvent(*channel, kDtmfEventCode,
84 kDtmfEventDurationMs));
85
86 // Program mock as operational that is ready to be stopped.
87 EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(true));
88 EXPECT_CALL(*audio_device_, Playing()).WillOnce(Return(true));
89 EXPECT_CALL(*audio_device_, StopRecording()).WillOnce(Return(0));
90 EXPECT_CALL(*audio_device_, StopPlayout()).WillOnce(Return(0));
91
92 EXPECT_TRUE(voip_core_->StopSend(*channel));
93 EXPECT_TRUE(voip_core_->StopPlayout(*channel));
94 voip_core_->ReleaseChannel(*channel);
95 }
96
TEST_F(VoipCoreTest,ExpectFailToUseReleasedChannelId)97 TEST_F(VoipCoreTest, ExpectFailToUseReleasedChannelId) {
98 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
99 EXPECT_TRUE(channel);
100
101 // Release right after creation.
102 voip_core_->ReleaseChannel(*channel);
103
104 // Now use released channel.
105
106 // These should be no-op.
107 voip_core_->SetSendCodec(*channel, kPcmuPayload, kPcmuFormat);
108 voip_core_->SetReceiveCodecs(*channel, {{kPcmuPayload, kPcmuFormat}});
109 voip_core_->RegisterTelephoneEventType(*channel, kPcmuPayload,
110 kPcmuSampleRateHz);
111
112 EXPECT_FALSE(voip_core_->StartSend(*channel));
113 EXPECT_FALSE(voip_core_->StartPlayout(*channel));
114 EXPECT_FALSE(voip_core_->SendDtmfEvent(*channel, kDtmfEventCode,
115 kDtmfEventDurationMs));
116 }
117
TEST_F(VoipCoreTest,SendDtmfEventWithoutRegistering)118 TEST_F(VoipCoreTest, SendDtmfEventWithoutRegistering) {
119 // Program mock as non-operational and ready to start send.
120 EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(false));
121 EXPECT_CALL(*audio_device_, InitRecording()).WillOnce(Return(0));
122 EXPECT_CALL(*audio_device_, StartRecording()).WillOnce(Return(0));
123
124 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
125 EXPECT_TRUE(channel);
126
127 voip_core_->SetSendCodec(*channel, kPcmuPayload, kPcmuFormat);
128
129 EXPECT_TRUE(voip_core_->StartSend(*channel));
130 // Send Dtmf event without registering beforehand, thus payload
131 // type is not set and false is expected.
132 EXPECT_FALSE(voip_core_->SendDtmfEvent(*channel, kDtmfEventCode,
133 kDtmfEventDurationMs));
134
135 // Program mock as sending and is ready to be stopped.
136 EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(true));
137 EXPECT_CALL(*audio_device_, StopRecording()).WillOnce(Return(0));
138
139 EXPECT_TRUE(voip_core_->StopSend(*channel));
140 voip_core_->ReleaseChannel(*channel);
141 }
142
TEST_F(VoipCoreTest,SendDtmfEventWithoutStartSend)143 TEST_F(VoipCoreTest, SendDtmfEventWithoutStartSend) {
144 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
145 EXPECT_TRUE(channel);
146
147 voip_core_->RegisterTelephoneEventType(*channel, kPcmuPayload,
148 kPcmuSampleRateHz);
149 // Send Dtmf event without calling StartSend beforehand, thus
150 // Dtmf events cannot be sent and false is expected.
151 EXPECT_FALSE(voip_core_->SendDtmfEvent(*channel, kDtmfEventCode,
152 kDtmfEventDurationMs));
153
154 voip_core_->ReleaseChannel(*channel);
155 }
156
TEST_F(VoipCoreTest,StartSendAndPlayoutWithoutSettingCodec)157 TEST_F(VoipCoreTest, StartSendAndPlayoutWithoutSettingCodec) {
158 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
159 EXPECT_TRUE(channel);
160
161 // Call StartSend and StartPlayout without setting send/receive
162 // codec. Code should see that codecs aren't set and return false.
163 EXPECT_FALSE(voip_core_->StartSend(*channel));
164 EXPECT_FALSE(voip_core_->StartPlayout(*channel));
165
166 voip_core_->ReleaseChannel(*channel);
167 }
168
TEST_F(VoipCoreTest,StopSendAndPlayoutWithoutStarting)169 TEST_F(VoipCoreTest, StopSendAndPlayoutWithoutStarting) {
170 auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
171 EXPECT_TRUE(channel);
172
173 voip_core_->SetSendCodec(*channel, kPcmuPayload, kPcmuFormat);
174 voip_core_->SetReceiveCodecs(*channel, {{kPcmuPayload, kPcmuFormat}});
175
176 // Call StopSend and StopPlayout without starting them in
177 // the first place. Should see that it is already in the
178 // stopped state and return true.
179 EXPECT_TRUE(voip_core_->StopSend(*channel));
180 EXPECT_TRUE(voip_core_->StopPlayout(*channel));
181
182 voip_core_->ReleaseChannel(*channel);
183 }
184
185 // This tests correctness on ProcessThread usage where we expect the first/last
186 // channel creation/release triggers its Start/Stop method once only.
TEST_F(VoipCoreTest,TestProcessThreadOperation)187 TEST_F(VoipCoreTest, TestProcessThreadOperation) {
188 EXPECT_CALL(*process_thread_, Start);
189 EXPECT_CALL(*process_thread_, RegisterModule).Times(2);
190
191 auto channel_one = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
192 auto channel_two = voip_core_->CreateChannel(&transport_, 0xdeadbeef);
193 EXPECT_TRUE(channel_one);
194 EXPECT_TRUE(channel_two);
195
196 EXPECT_CALL(*process_thread_, Stop);
197 EXPECT_CALL(*process_thread_, DeRegisterModule).Times(2);
198
199 voip_core_->ReleaseChannel(*channel_one);
200 voip_core_->ReleaseChannel(*channel_two);
201
202 EXPECT_CALL(*process_thread_, Start);
203 EXPECT_CALL(*process_thread_, RegisterModule);
204
205 auto channel_three = voip_core_->CreateChannel(&transport_, absl::nullopt);
206 EXPECT_TRUE(channel_three);
207
208 EXPECT_CALL(*process_thread_, Stop);
209 EXPECT_CALL(*process_thread_, DeRegisterModule);
210
211 voip_core_->ReleaseChannel(*channel_three);
212 }
213
214 } // namespace
215 } // namespace webrtc
216