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