1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/test/test_timeouts.h"
10 #include "media/audio/audio_input_controller.h"
11 #include "media/audio/audio_manager_base.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 using ::testing::AtLeast
;
17 using ::testing::Exactly
;
18 using ::testing::InvokeWithoutArgs
;
19 using ::testing::NotNull
;
23 static const int kSampleRate
= AudioParameters::kAudioCDSampleRate
;
24 static const int kBitsPerSample
= 16;
25 static const ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_STEREO
;
26 static const int kSamplesPerPacket
= kSampleRate
/ 10;
28 // Posts base::MessageLoop::QuitClosure() on specified message loop.
29 ACTION_P(QuitMessageLoop
, loop_or_proxy
) {
30 loop_or_proxy
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
33 // Posts base::MessageLoop::QuitClosure() on specified message loop after a
34 // certain number of calls given by |limit|.
35 ACTION_P3(CheckCountAndPostQuitTask
, count
, limit
, loop_or_proxy
) {
36 if (++*count
>= limit
) {
37 loop_or_proxy
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
41 // Closes AudioOutputController synchronously.
42 static void CloseAudioController(AudioInputController
* controller
) {
43 controller
->Close(base::MessageLoop::QuitClosure());
44 base::MessageLoop::current()->Run();
47 class MockAudioInputControllerEventHandler
48 : public AudioInputController::EventHandler
{
50 MockAudioInputControllerEventHandler() {}
52 MOCK_METHOD1(OnCreated
, void(AudioInputController
* controller
));
53 MOCK_METHOD1(OnRecording
, void(AudioInputController
* controller
));
54 MOCK_METHOD2(OnError
, void(AudioInputController
* controller
,
55 AudioInputController::ErrorCode error_code
));
56 MOCK_METHOD3(OnData
, void(AudioInputController
* controller
,
57 const uint8
* data
, uint32 size
));
60 DISALLOW_COPY_AND_ASSIGN(MockAudioInputControllerEventHandler
);
64 class AudioInputControllerTest
: public testing::Test
{
66 AudioInputControllerTest() {}
67 virtual ~AudioInputControllerTest() {}
70 base::MessageLoop message_loop_
;
73 DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest
);
76 // Test AudioInputController for create and close without recording audio.
77 TEST_F(AudioInputControllerTest
, CreateAndClose
) {
78 MockAudioInputControllerEventHandler event_handler
;
80 // OnCreated() will be posted once.
81 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
82 .WillOnce(QuitMessageLoop(&message_loop_
));
84 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
85 AudioParameters
params(AudioParameters::AUDIO_FAKE
, kChannelLayout
,
86 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
88 scoped_refptr
<AudioInputController
> controller
=
89 AudioInputController::Create(audio_manager
.get(),
92 AudioManagerBase::kDefaultDeviceId
,
94 ASSERT_TRUE(controller
.get());
96 // Wait for OnCreated() to fire.
99 // Close the AudioInputController synchronously.
100 CloseAudioController(controller
.get());
103 // Test a normal call sequence of create, record and close.
104 TEST_F(AudioInputControllerTest
, RecordAndClose
) {
105 MockAudioInputControllerEventHandler event_handler
;
108 // OnCreated() will be called once.
109 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
112 // OnRecording() will be called only once.
113 EXPECT_CALL(event_handler
, OnRecording(NotNull()))
116 // OnData() shall be called ten times.
117 EXPECT_CALL(event_handler
, OnData(NotNull(), NotNull(), _
))
119 .WillRepeatedly(CheckCountAndPostQuitTask(&count
, 10,
120 message_loop_
.message_loop_proxy()));
122 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
123 AudioParameters
params(AudioParameters::AUDIO_FAKE
, kChannelLayout
,
124 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
126 // Creating the AudioInputController should render an OnCreated() call.
127 scoped_refptr
<AudioInputController
> controller
=
128 AudioInputController::Create(audio_manager
.get(),
131 AudioManagerBase::kDefaultDeviceId
,
133 ASSERT_TRUE(controller
.get());
135 // Start recording and trigger one OnRecording() call.
136 controller
->Record();
138 // Record and wait until ten OnData() callbacks are received.
141 // Close the AudioInputController synchronously.
142 CloseAudioController(controller
.get());
145 // Test that the AudioInputController reports an error when the input stream
146 // stops. This can happen when the underlying audio layer stops feeding data as
147 // a result of a removed microphone device.
148 // Disabled due to crbug.com/357569 and crbug.com/357501.
149 // TODO(henrika): Remove the test when the timer workaround has been removed.
150 TEST_F(AudioInputControllerTest
, DISABLED_RecordAndError
) {
151 MockAudioInputControllerEventHandler event_handler
;
154 // OnCreated() will be called once.
155 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
158 // OnRecording() will be called only once.
159 EXPECT_CALL(event_handler
, OnRecording(NotNull()))
162 // OnData() shall be called ten times.
163 EXPECT_CALL(event_handler
, OnData(NotNull(), NotNull(), _
))
165 .WillRepeatedly(CheckCountAndPostQuitTask(&count
, 10,
166 message_loop_
.message_loop_proxy()));
168 // OnError() will be called after the data stream stops while the
169 // controller is in a recording state.
170 EXPECT_CALL(event_handler
, OnError(NotNull(),
171 AudioInputController::NO_DATA_ERROR
))
173 .WillOnce(QuitMessageLoop(&message_loop_
));
175 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
176 AudioParameters
params(AudioParameters::AUDIO_FAKE
, kChannelLayout
,
177 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
179 // Creating the AudioInputController should render an OnCreated() call.
180 scoped_refptr
<AudioInputController
> controller
=
181 AudioInputController::Create(audio_manager
.get(),
184 AudioManagerBase::kDefaultDeviceId
,
186 ASSERT_TRUE(controller
.get());
188 // Start recording and trigger one OnRecording() call.
189 controller
->Record();
191 // Record and wait until ten OnData() callbacks are received.
194 // Stop the stream and verify that OnError() is posted.
195 AudioInputStream
* stream
= controller
->stream_for_testing();
199 // Close the AudioInputController synchronously.
200 CloseAudioController(controller
.get());
203 // Test that AudioInputController rejects insanely large packet sizes.
204 TEST_F(AudioInputControllerTest
, SamplesPerPacketTooLarge
) {
205 // Create an audio device with a very large packet size.
206 MockAudioInputControllerEventHandler event_handler
;
208 // OnCreated() shall not be called in this test.
209 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
212 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
213 AudioParameters
params(AudioParameters::AUDIO_FAKE
,
217 kSamplesPerPacket
* 1000);
218 scoped_refptr
<AudioInputController
> controller
=
219 AudioInputController::Create(audio_manager
.get(),
222 AudioManagerBase::kDefaultDeviceId
,
224 ASSERT_FALSE(controller
.get());
227 // Test calling AudioInputController::Close multiple times.
228 TEST_F(AudioInputControllerTest
, CloseTwice
) {
229 MockAudioInputControllerEventHandler event_handler
;
231 // OnRecording() will be called only once.
232 EXPECT_CALL(event_handler
, OnCreated(NotNull()));
234 // OnRecording() will be called only once.
235 EXPECT_CALL(event_handler
, OnRecording(NotNull()))
238 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
239 AudioParameters
params(AudioParameters::AUDIO_FAKE
,
244 scoped_refptr
<AudioInputController
> controller
=
245 AudioInputController::Create(audio_manager
.get(),
248 AudioManagerBase::kDefaultDeviceId
,
250 ASSERT_TRUE(controller
.get());
252 controller
->Record();
254 controller
->Close(base::MessageLoop::QuitClosure());
255 base::MessageLoop::current()->Run();
257 controller
->Close(base::MessageLoop::QuitClosure());
258 base::MessageLoop::current()->Run();