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