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.
4
5 #include "base/basictypes.h"
6 #include "base/bind.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"
14
15 using ::testing::_;
16 using ::testing::AtLeast;
17 using ::testing::Exactly;
18 using ::testing::InvokeWithoutArgs;
19 using ::testing::NotNull;
20
21 namespace media {
22
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;
27
28 // Posts base::MessageLoop::QuitClosure() on specified message loop.
ACTION_P(QuitMessageLoop,loop_or_proxy)29 ACTION_P(QuitMessageLoop, loop_or_proxy) {
30 loop_or_proxy->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
31 }
32
33 // Posts base::MessageLoop::QuitClosure() on specified message loop after a
34 // certain number of calls given by |limit|.
ACTION_P3(CheckCountAndPostQuitTask,count,limit,loop_or_proxy)35 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop_or_proxy) {
36 if (++*count >= limit) {
37 loop_or_proxy->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
38 }
39 }
40
41 // Closes AudioOutputController synchronously.
CloseAudioController(AudioInputController * controller)42 static void CloseAudioController(AudioInputController* controller) {
43 controller->Close(base::MessageLoop::QuitClosure());
44 base::MessageLoop::current()->Run();
45 }
46
47 class MockAudioInputControllerEventHandler
48 : public AudioInputController::EventHandler {
49 public:
MockAudioInputControllerEventHandler()50 MockAudioInputControllerEventHandler() {}
51
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_METHOD2(OnData,
57 void(AudioInputController* controller, const AudioBus* data));
58 MOCK_METHOD2(OnLog,
59 void(AudioInputController* controller,
60 const std::string& message));
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(MockAudioInputControllerEventHandler);
64 };
65
66 // Test fixture.
67 class AudioInputControllerTest : public testing::Test {
68 public:
AudioInputControllerTest()69 AudioInputControllerTest() {}
~AudioInputControllerTest()70 virtual ~AudioInputControllerTest() {}
71
72 protected:
73 base::MessageLoop message_loop_;
74
75 private:
76 DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest);
77 };
78
79 // Test AudioInputController for create and close without recording audio.
TEST_F(AudioInputControllerTest,CreateAndClose)80 TEST_F(AudioInputControllerTest, CreateAndClose) {
81 MockAudioInputControllerEventHandler event_handler;
82
83 // OnCreated() will be posted once.
84 EXPECT_CALL(event_handler, OnCreated(NotNull()))
85 .WillOnce(QuitMessageLoop(&message_loop_));
86
87 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
88 AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
89 kSampleRate, kBitsPerSample, kSamplesPerPacket);
90
91 scoped_refptr<AudioInputController> controller =
92 AudioInputController::Create(audio_manager.get(),
93 &event_handler,
94 params,
95 AudioManagerBase::kDefaultDeviceId,
96 NULL);
97 ASSERT_TRUE(controller.get());
98
99 // Wait for OnCreated() to fire.
100 message_loop_.Run();
101
102 // Close the AudioInputController synchronously.
103 CloseAudioController(controller.get());
104 }
105
106 // Test a normal call sequence of create, record and close.
TEST_F(AudioInputControllerTest,RecordAndClose)107 TEST_F(AudioInputControllerTest, RecordAndClose) {
108 MockAudioInputControllerEventHandler event_handler;
109 int count = 0;
110
111 // OnCreated() will be called once.
112 EXPECT_CALL(event_handler, OnCreated(NotNull()))
113 .Times(Exactly(1));
114
115 // OnRecording() will be called only once.
116 EXPECT_CALL(event_handler, OnRecording(NotNull()))
117 .Times(Exactly(1));
118
119 // OnData() shall be called ten times.
120 EXPECT_CALL(event_handler, OnData(NotNull(), NotNull()))
121 .Times(AtLeast(10))
122 .WillRepeatedly(CheckCountAndPostQuitTask(
123 &count, 10, message_loop_.message_loop_proxy()));
124
125 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
126 AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
127 kSampleRate, kBitsPerSample, kSamplesPerPacket);
128
129 // Creating the AudioInputController should render an OnCreated() call.
130 scoped_refptr<AudioInputController> controller =
131 AudioInputController::Create(audio_manager.get(),
132 &event_handler,
133 params,
134 AudioManagerBase::kDefaultDeviceId,
135 NULL);
136 ASSERT_TRUE(controller.get());
137
138 // Start recording and trigger one OnRecording() call.
139 controller->Record();
140
141 // Record and wait until ten OnData() callbacks are received.
142 message_loop_.Run();
143
144 // Close the AudioInputController synchronously.
145 CloseAudioController(controller.get());
146 }
147
148 // Test that the AudioInputController reports an error when the input stream
149 // stops. This can happen when the underlying audio layer stops feeding data as
150 // a result of a removed microphone device.
151 // Disabled due to crbug.com/357569 and crbug.com/357501.
152 // TODO(henrika): Remove the test when the timer workaround has been removed.
TEST_F(AudioInputControllerTest,DISABLED_RecordAndError)153 TEST_F(AudioInputControllerTest, DISABLED_RecordAndError) {
154 MockAudioInputControllerEventHandler event_handler;
155 int count = 0;
156
157 // OnCreated() will be called once.
158 EXPECT_CALL(event_handler, OnCreated(NotNull()))
159 .Times(Exactly(1));
160
161 // OnRecording() will be called only once.
162 EXPECT_CALL(event_handler, OnRecording(NotNull()))
163 .Times(Exactly(1));
164
165 // OnData() shall be called ten times.
166 EXPECT_CALL(event_handler, OnData(NotNull(), NotNull()))
167 .Times(AtLeast(10))
168 .WillRepeatedly(CheckCountAndPostQuitTask(
169 &count, 10, message_loop_.message_loop_proxy()));
170
171 // OnError() will be called after the data stream stops while the
172 // controller is in a recording state.
173 EXPECT_CALL(event_handler, OnError(NotNull(),
174 AudioInputController::NO_DATA_ERROR))
175 .Times(Exactly(1))
176 .WillOnce(QuitMessageLoop(&message_loop_));
177
178 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
179 AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
180 kSampleRate, kBitsPerSample, kSamplesPerPacket);
181
182 // Creating the AudioInputController should render an OnCreated() call.
183 scoped_refptr<AudioInputController> controller =
184 AudioInputController::Create(audio_manager.get(),
185 &event_handler,
186 params,
187 AudioManagerBase::kDefaultDeviceId,
188 NULL);
189 ASSERT_TRUE(controller.get());
190
191 // Start recording and trigger one OnRecording() call.
192 controller->Record();
193
194 // Record and wait until ten OnData() callbacks are received.
195 message_loop_.Run();
196
197 // Stop the stream and verify that OnError() is posted.
198 AudioInputStream* stream = controller->stream_for_testing();
199 stream->Stop();
200 message_loop_.Run();
201
202 // Close the AudioInputController synchronously.
203 CloseAudioController(controller.get());
204 }
205
206 // Test that AudioInputController rejects insanely large packet sizes.
TEST_F(AudioInputControllerTest,SamplesPerPacketTooLarge)207 TEST_F(AudioInputControllerTest, SamplesPerPacketTooLarge) {
208 // Create an audio device with a very large packet size.
209 MockAudioInputControllerEventHandler event_handler;
210
211 // OnCreated() shall not be called in this test.
212 EXPECT_CALL(event_handler, OnCreated(NotNull()))
213 .Times(Exactly(0));
214
215 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
216 AudioParameters params(AudioParameters::AUDIO_FAKE,
217 kChannelLayout,
218 kSampleRate,
219 kBitsPerSample,
220 kSamplesPerPacket * 1000);
221 scoped_refptr<AudioInputController> controller =
222 AudioInputController::Create(audio_manager.get(),
223 &event_handler,
224 params,
225 AudioManagerBase::kDefaultDeviceId,
226 NULL);
227 ASSERT_FALSE(controller.get());
228 }
229
230 // Test calling AudioInputController::Close multiple times.
TEST_F(AudioInputControllerTest,CloseTwice)231 TEST_F(AudioInputControllerTest, CloseTwice) {
232 MockAudioInputControllerEventHandler event_handler;
233
234 // OnRecording() will be called only once.
235 EXPECT_CALL(event_handler, OnCreated(NotNull()));
236
237 // OnRecording() will be called only once.
238 EXPECT_CALL(event_handler, OnRecording(NotNull()))
239 .Times(Exactly(1));
240
241 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
242 AudioParameters params(AudioParameters::AUDIO_FAKE,
243 kChannelLayout,
244 kSampleRate,
245 kBitsPerSample,
246 kSamplesPerPacket);
247 scoped_refptr<AudioInputController> controller =
248 AudioInputController::Create(audio_manager.get(),
249 &event_handler,
250 params,
251 AudioManagerBase::kDefaultDeviceId,
252 NULL);
253 ASSERT_TRUE(controller.get());
254
255 controller->Record();
256
257 controller->Close(base::MessageLoop::QuitClosure());
258 base::MessageLoop::current()->Run();
259
260 controller->Close(base::MessageLoop::QuitClosure());
261 base::MessageLoop::current()->Run();
262 }
263
264 } // namespace media
265