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_METHOD1(OnError, void(AudioInputController* controller));
55  MOCK_METHOD3(OnData, void(AudioInputController* controller,
56                            const uint8* data, uint32 size));
57
58 private:
59  DISALLOW_COPY_AND_ASSIGN(MockAudioInputControllerEventHandler);
60};
61
62// Test fixture.
63class AudioInputControllerTest : public testing::Test {
64 public:
65  AudioInputControllerTest() {}
66  virtual ~AudioInputControllerTest() {}
67
68 protected:
69  base::MessageLoop message_loop_;
70
71 private:
72  DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest);
73};
74
75// Test AudioInputController for create and close without recording audio.
76TEST_F(AudioInputControllerTest, CreateAndClose) {
77  MockAudioInputControllerEventHandler event_handler;
78
79  // OnCreated() will be posted once.
80  EXPECT_CALL(event_handler, OnCreated(NotNull()))
81      .WillOnce(QuitMessageLoop(&message_loop_));
82
83  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
84  AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
85                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
86
87  scoped_refptr<AudioInputController> controller =
88      AudioInputController::Create(audio_manager.get(),
89                                   &event_handler,
90                                   params,
91                                   AudioManagerBase::kDefaultDeviceId,
92                                   NULL);
93  ASSERT_TRUE(controller.get());
94
95  // Wait for OnCreated() to fire.
96  message_loop_.Run();
97
98  // Close the AudioInputController synchronously.
99  CloseAudioController(controller.get());
100}
101
102// Test a normal call sequence of create, record and close.
103TEST_F(AudioInputControllerTest, RecordAndClose) {
104  MockAudioInputControllerEventHandler event_handler;
105  int count = 0;
106
107  // OnCreated() will be called once.
108  EXPECT_CALL(event_handler, OnCreated(NotNull()))
109      .Times(Exactly(1));
110
111  // OnRecording() will be called only once.
112  EXPECT_CALL(event_handler, OnRecording(NotNull()))
113      .Times(Exactly(1));
114
115  // OnData() shall be called ten times.
116  EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _))
117      .Times(AtLeast(10))
118      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10,
119          message_loop_.message_loop_proxy()));
120
121  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
122  AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
123                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
124
125  // Creating the AudioInputController should render an OnCreated() call.
126  scoped_refptr<AudioInputController> controller =
127      AudioInputController::Create(audio_manager.get(),
128                                   &event_handler,
129                                   params,
130                                   AudioManagerBase::kDefaultDeviceId,
131                                   NULL);
132  ASSERT_TRUE(controller.get());
133
134  // Start recording and trigger one OnRecording() call.
135  controller->Record();
136
137  // Record and wait until ten OnData() callbacks are received.
138  message_loop_.Run();
139
140  // Close the AudioInputController synchronously.
141  CloseAudioController(controller.get());
142}
143
144// Test that the AudioInputController reports an error when the input stream
145// stops without an OnClose() callback. This can happen when the underlying
146// audio layer stops feeding data as a result of a removed microphone device.
147TEST_F(AudioInputControllerTest, RecordAndError) {
148  MockAudioInputControllerEventHandler event_handler;
149  int count = 0;
150
151  // OnCreated() will be called once.
152  EXPECT_CALL(event_handler, OnCreated(NotNull()))
153      .Times(Exactly(1));
154
155  // OnRecording() will be called only once.
156  EXPECT_CALL(event_handler, OnRecording(NotNull()))
157      .Times(Exactly(1));
158
159  // OnData() shall be called ten times.
160  EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _))
161      .Times(AtLeast(10))
162      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10,
163          message_loop_.message_loop_proxy()));
164
165  // OnError() will be called after the data stream stops while the
166  // controller is in a recording state.
167  EXPECT_CALL(event_handler, OnError(NotNull()))
168      .Times(Exactly(1))
169      .WillOnce(QuitMessageLoop(&message_loop_));
170
171  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
172  AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
173                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
174
175  // Creating the AudioInputController should render an OnCreated() call.
176  scoped_refptr<AudioInputController> controller =
177      AudioInputController::Create(audio_manager.get(),
178                                   &event_handler,
179                                   params,
180                                   AudioManagerBase::kDefaultDeviceId,
181                                   NULL);
182  ASSERT_TRUE(controller.get());
183
184  // Start recording and trigger one OnRecording() call.
185  controller->Record();
186
187  // Record and wait until ten OnData() callbacks are received.
188  message_loop_.Run();
189
190  // Stop the stream and verify that OnError() is posted.
191  AudioInputStream* stream = controller->stream_for_testing();
192  stream->Stop();
193  message_loop_.Run();
194
195  // Close the AudioInputController synchronously.
196  CloseAudioController(controller.get());
197}
198
199// Test that AudioInputController rejects insanely large packet sizes.
200TEST_F(AudioInputControllerTest, SamplesPerPacketTooLarge) {
201  // Create an audio device with a very large packet size.
202  MockAudioInputControllerEventHandler event_handler;
203
204  // OnCreated() shall not be called in this test.
205  EXPECT_CALL(event_handler, OnCreated(NotNull()))
206    .Times(Exactly(0));
207
208  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
209  AudioParameters params(AudioParameters::AUDIO_FAKE,
210                         kChannelLayout,
211                         kSampleRate,
212                         kBitsPerSample,
213                         kSamplesPerPacket * 1000);
214  scoped_refptr<AudioInputController> controller =
215      AudioInputController::Create(audio_manager.get(),
216                                   &event_handler,
217                                   params,
218                                   AudioManagerBase::kDefaultDeviceId,
219                                   NULL);
220  ASSERT_FALSE(controller.get());
221}
222
223// Test calling AudioInputController::Close multiple times.
224TEST_F(AudioInputControllerTest, CloseTwice) {
225  MockAudioInputControllerEventHandler event_handler;
226
227  // OnRecording() will be called only once.
228  EXPECT_CALL(event_handler, OnCreated(NotNull()));
229
230  // OnRecording() will be called only once.
231  EXPECT_CALL(event_handler, OnRecording(NotNull()))
232      .Times(Exactly(1));
233
234  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
235  AudioParameters params(AudioParameters::AUDIO_FAKE,
236                         kChannelLayout,
237                         kSampleRate,
238                         kBitsPerSample,
239                         kSamplesPerPacket);
240  scoped_refptr<AudioInputController> controller =
241      AudioInputController::Create(audio_manager.get(),
242                                   &event_handler,
243                                   params,
244                                   AudioManagerBase::kDefaultDeviceId,
245                                   NULL);
246  ASSERT_TRUE(controller.get());
247
248  controller->Record();
249
250  controller->Close(base::MessageLoop::QuitClosure());
251  base::MessageLoop::current()->Run();
252
253  controller->Close(base::MessageLoop::QuitClosure());
254  base::MessageLoop::current()->Run();
255}
256
257}  // namespace media
258