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.
5 #include "base/basictypes.h"
6 #include "base/environment.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/platform_thread.h"
12 #include "media/audio/audio_io.h"
13 #include "media/audio/audio_manager_base.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 // This class allows to find out if the callbacks are occurring as
19 // expected and if any error has been reported.
20 class TestInputCallback
: public AudioInputStream::AudioInputCallback
{
22 explicit TestInputCallback()
26 virtual void OnData(AudioInputStream
* stream
,
27 const AudioBus
* source
,
28 uint32 hardware_delay_bytes
,
29 double volume
) OVERRIDE
{
32 virtual void OnError(AudioInputStream
* stream
) OVERRIDE
{
35 // Returns how many times OnData() has been called.
36 int callback_count() const {
37 return callback_count_
;
39 // Returns how many times the OnError callback was called.
40 int had_error() const {
49 class AudioInputTest
: public testing::Test
{
52 message_loop_(base::MessageLoop::TYPE_UI
),
53 audio_manager_(AudioManager::CreateForTesting()),
54 audio_input_stream_(NULL
) {
55 // Wait for the AudioManager to finish any initialization on the audio loop.
56 base::RunLoop().RunUntilIdle();
59 virtual ~AudioInputTest() {
60 base::RunLoop().RunUntilIdle();
64 AudioManager
* audio_manager() { return audio_manager_
.get(); }
66 bool CanRunAudioTests() {
67 bool has_input
= audio_manager()->HasAudioInputDevices();
68 LOG_IF(WARNING
, !has_input
) << "No input devices detected";
72 void MakeAudioInputStreamOnAudioThread() {
74 base::Bind(&AudioInputTest::MakeAudioInputStream
,
75 base::Unretained(this)));
78 void CloseAudioInputStreamOnAudioThread() {
80 base::Bind(&AudioInputStream::Close
,
81 base::Unretained(audio_input_stream_
)));
82 audio_input_stream_
= NULL
;
85 void OpenAndCloseAudioInputStreamOnAudioThread() {
87 base::Bind(&AudioInputTest::OpenAndClose
,
88 base::Unretained(this)));
91 void OpenStopAndCloseAudioInputStreamOnAudioThread() {
93 base::Bind(&AudioInputTest::OpenStopAndClose
,
94 base::Unretained(this)));
97 void OpenAndStartAudioInputStreamOnAudioThread(
98 AudioInputStream::AudioInputCallback
* sink
) {
100 base::Bind(&AudioInputTest::OpenAndStart
,
101 base::Unretained(this),
105 void StopAndCloseAudioInputStreamOnAudioThread() {
107 base::Bind(&AudioInputTest::StopAndClose
,
108 base::Unretained(this)));
111 void MakeAudioInputStream() {
112 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
113 AudioParameters params
= audio_manager()->GetInputStreamParameters(
114 AudioManagerBase::kDefaultDeviceId
);
115 audio_input_stream_
= audio_manager()->MakeAudioInputStream(params
,
116 AudioManagerBase::kDefaultDeviceId
);
117 EXPECT_TRUE(audio_input_stream_
);
120 void OpenAndClose() {
121 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
122 EXPECT_TRUE(audio_input_stream_
->Open());
123 audio_input_stream_
->Close();
124 audio_input_stream_
= NULL
;
127 void OpenAndStart(AudioInputStream::AudioInputCallback
* sink
) {
128 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
129 EXPECT_TRUE(audio_input_stream_
->Open());
130 audio_input_stream_
->Start(sink
);
133 void OpenStopAndClose() {
134 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
135 EXPECT_TRUE(audio_input_stream_
->Open());
136 audio_input_stream_
->Stop();
137 audio_input_stream_
->Close();
138 audio_input_stream_
= NULL
;
141 void StopAndClose() {
142 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
143 audio_input_stream_
->Stop();
144 audio_input_stream_
->Close();
145 audio_input_stream_
= NULL
;
148 // Synchronously runs the provided callback/closure on the audio thread.
149 void RunOnAudioThread(const base::Closure
& closure
) {
150 if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) {
151 base::WaitableEvent
event(false, false);
152 audio_manager()->GetTaskRunner()->PostTask(
154 base::Bind(&AudioInputTest::RunOnAudioThreadImpl
,
155 base::Unretained(this),
164 void RunOnAudioThreadImpl(const base::Closure
& closure
,
165 base::WaitableEvent
* event
) {
166 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
171 base::MessageLoop message_loop_
;
172 scoped_ptr
<AudioManager
> audio_manager_
;
173 AudioInputStream
* audio_input_stream_
;
176 DISALLOW_COPY_AND_ASSIGN(AudioInputTest
);
179 // Test create and close of an AudioInputStream without recording audio.
180 TEST_F(AudioInputTest
, CreateAndClose
) {
181 if (!CanRunAudioTests())
183 MakeAudioInputStreamOnAudioThread();
184 CloseAudioInputStreamOnAudioThread();
187 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
188 // This test is failing on ARM linux: http://crbug.com/238490
189 #define MAYBE_OpenAndClose DISABLED_OpenAndClose
191 #define MAYBE_OpenAndClose OpenAndClose
193 // Test create, open and close of an AudioInputStream without recording audio.
194 TEST_F(AudioInputTest
, MAYBE_OpenAndClose
) {
195 if (!CanRunAudioTests())
197 MakeAudioInputStreamOnAudioThread();
198 OpenAndCloseAudioInputStreamOnAudioThread();
201 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
202 // This test is failing on ARM linux: http://crbug.com/238490
203 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose
205 #define MAYBE_OpenStopAndClose OpenStopAndClose
207 // Test create, open, stop and close of an AudioInputStream without recording.
208 TEST_F(AudioInputTest
, MAYBE_OpenStopAndClose
) {
209 if (!CanRunAudioTests())
211 MakeAudioInputStreamOnAudioThread();
212 OpenStopAndCloseAudioInputStreamOnAudioThread();
215 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
216 // This test is failing on ARM linux: http://crbug.com/238490
217 #define MAYBE_Record DISABLED_Record
219 #define MAYBE_Record Record
221 // Test a normal recording sequence using an AudioInputStream.
222 // Very simple test which starts capturing during half a second and verifies
223 // that recording starts.
224 TEST_F(AudioInputTest
, MAYBE_Record
) {
225 if (!CanRunAudioTests())
227 MakeAudioInputStreamOnAudioThread();
229 TestInputCallback test_callback
;
230 OpenAndStartAudioInputStreamOnAudioThread(&test_callback
);
232 message_loop_
.PostDelayedTask(
234 base::MessageLoop::QuitClosure(),
235 base::TimeDelta::FromMilliseconds(500));
237 EXPECT_GE(test_callback
.callback_count(), 2);
238 EXPECT_FALSE(test_callback
.had_error());
240 StopAndCloseAudioInputStreamOnAudioThread();