audio_input_controller_unittest.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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
15using ::testing::_;
16using ::testing::AtLeast;
17using ::testing::Exactly;
18using ::testing::InvokeWithoutArgs;
19using ::testing::NotNull;
20
21namespace media {
22
23static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
24static const int kBitsPerSample = 16;
25static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
26static const int kSamplesPerPacket = kSampleRate / 10;
27
28// Posts base::MessageLoop::QuitClosure() on specified message loop.
29ACTION_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|.
35ACTION_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.
42static void CloseAudioController(AudioInputController* controller) {
43  controller->Close(base::MessageLoop::QuitClosure());
44  base::MessageLoop::current()->Run();
45}
46
47class MockAudioInputControllerEventHandler
48    : public AudioInputController::EventHandler {
49 public:
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.
67class AudioInputControllerTest : public testing::Test {
68 public:
69  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.
80TEST_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.
107TEST_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.
153TEST_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.
207TEST_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.
231TEST_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