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