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