Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / audio / audio_input_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/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"
15
16 namespace media {
17
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 {
21  public:
22   explicit TestInputCallback()
23       : callback_count_(0),
24         had_error_(0) {
25   }
26   virtual void OnData(AudioInputStream* stream,
27                       const uint8* data,
28                       uint32 size,
29                       uint32 hardware_delay_bytes,
30                       double volume) OVERRIDE {
31     ++callback_count_;
32   }
33   virtual void OnError(AudioInputStream* stream) OVERRIDE {
34     ++had_error_;
35   }
36   // Returns how many times OnData() has been called.
37   int callback_count() const {
38     return callback_count_;
39   }
40   // Returns how many times the OnError callback was called.
41   int had_error() const {
42     return had_error_;
43   }
44
45  private:
46   int callback_count_;
47   int had_error_;
48 };
49
50 class AudioInputTest : public testing::Test {
51   public:
52    AudioInputTest() :
53       message_loop_(base::MessageLoop::TYPE_UI),
54       audio_manager_(AudioManager::CreateForTesting()),
55       audio_input_stream_(NULL) {
56     // Wait for the AudioManager to finish any initialization on the audio loop.
57     base::RunLoop().RunUntilIdle();
58   }
59
60   virtual ~AudioInputTest() {
61     base::RunLoop().RunUntilIdle();
62   }
63
64  protected:
65   AudioManager* audio_manager() { return audio_manager_.get(); }
66
67   bool CanRunAudioTests() {
68     bool has_input = audio_manager()->HasAudioInputDevices();
69     LOG_IF(WARNING, !has_input) << "No input devices detected";
70     return has_input;
71   }
72
73   void MakeAudioInputStreamOnAudioThread() {
74     RunOnAudioThread(
75         base::Bind(&AudioInputTest::MakeAudioInputStream,
76                    base::Unretained(this)));
77   }
78
79   void CloseAudioInputStreamOnAudioThread() {
80     RunOnAudioThread(
81         base::Bind(&AudioInputStream::Close,
82                    base::Unretained(audio_input_stream_)));
83     audio_input_stream_ = NULL;
84   }
85
86   void OpenAndCloseAudioInputStreamOnAudioThread() {
87     RunOnAudioThread(
88         base::Bind(&AudioInputTest::OpenAndClose,
89                    base::Unretained(this)));
90   }
91
92   void OpenStopAndCloseAudioInputStreamOnAudioThread() {
93     RunOnAudioThread(
94         base::Bind(&AudioInputTest::OpenStopAndClose,
95                    base::Unretained(this)));
96   }
97
98   void OpenAndStartAudioInputStreamOnAudioThread(
99       AudioInputStream::AudioInputCallback* sink) {
100     RunOnAudioThread(
101         base::Bind(&AudioInputTest::OpenAndStart,
102                    base::Unretained(this),
103                    sink));
104   }
105
106   void StopAndCloseAudioInputStreamOnAudioThread() {
107     RunOnAudioThread(
108         base::Bind(&AudioInputTest::StopAndClose,
109                    base::Unretained(this)));
110   }
111
112   void MakeAudioInputStream() {
113     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
114     AudioParameters params = audio_manager()->GetInputStreamParameters(
115         AudioManagerBase::kDefaultDeviceId);
116     audio_input_stream_ = audio_manager()->MakeAudioInputStream(params,
117         AudioManagerBase::kDefaultDeviceId);
118     EXPECT_TRUE(audio_input_stream_);
119   }
120
121   void OpenAndClose() {
122     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
123     EXPECT_TRUE(audio_input_stream_->Open());
124     audio_input_stream_->Close();
125     audio_input_stream_ = NULL;
126   }
127
128   void OpenAndStart(AudioInputStream::AudioInputCallback* sink) {
129     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
130     EXPECT_TRUE(audio_input_stream_->Open());
131     audio_input_stream_->Start(sink);
132   }
133
134   void OpenStopAndClose() {
135     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
136     EXPECT_TRUE(audio_input_stream_->Open());
137     audio_input_stream_->Stop();
138     audio_input_stream_->Close();
139     audio_input_stream_ = NULL;
140   }
141
142   void StopAndClose() {
143     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
144     audio_input_stream_->Stop();
145     audio_input_stream_->Close();
146     audio_input_stream_ = NULL;
147   }
148
149   // Synchronously runs the provided callback/closure on the audio thread.
150   void RunOnAudioThread(const base::Closure& closure) {
151     if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) {
152       base::WaitableEvent event(false, false);
153       audio_manager()->GetTaskRunner()->PostTask(
154           FROM_HERE,
155           base::Bind(&AudioInputTest::RunOnAudioThreadImpl,
156                      base::Unretained(this),
157                      closure,
158                      &event));
159       event.Wait();
160     } else {
161       closure.Run();
162     }
163   }
164
165   void RunOnAudioThreadImpl(const base::Closure& closure,
166                             base::WaitableEvent* event) {
167     DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
168     closure.Run();
169     event->Signal();
170   }
171
172   base::MessageLoop message_loop_;
173   scoped_ptr<AudioManager> audio_manager_;
174   AudioInputStream* audio_input_stream_;
175
176  private:
177   DISALLOW_COPY_AND_ASSIGN(AudioInputTest);
178 };
179
180 // Test create and close of an AudioInputStream without recording audio.
181 TEST_F(AudioInputTest, CreateAndClose) {
182   if (!CanRunAudioTests())
183     return;
184   MakeAudioInputStreamOnAudioThread();
185   CloseAudioInputStreamOnAudioThread();
186 }
187
188 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
189 // This test is failing on ARM linux: http://crbug.com/238490
190 #define MAYBE_OpenAndClose DISABLED_OpenAndClose
191 #else
192 #define MAYBE_OpenAndClose OpenAndClose
193 #endif
194 // Test create, open and close of an AudioInputStream without recording audio.
195 TEST_F(AudioInputTest, MAYBE_OpenAndClose) {
196   if (!CanRunAudioTests())
197     return;
198   MakeAudioInputStreamOnAudioThread();
199   OpenAndCloseAudioInputStreamOnAudioThread();
200 }
201
202 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
203 // This test is failing on ARM linux: http://crbug.com/238490
204 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose
205 #else
206 #define MAYBE_OpenStopAndClose OpenStopAndClose
207 #endif
208 // Test create, open, stop and close of an AudioInputStream without recording.
209 TEST_F(AudioInputTest, MAYBE_OpenStopAndClose) {
210   if (!CanRunAudioTests())
211     return;
212   MakeAudioInputStreamOnAudioThread();
213   OpenStopAndCloseAudioInputStreamOnAudioThread();
214 }
215
216 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
217 // This test is failing on ARM linux: http://crbug.com/238490
218 #define MAYBE_Record DISABLED_Record
219 #else
220 #define MAYBE_Record Record
221 #endif
222 // Test a normal recording sequence using an AudioInputStream.
223 // Very simple test which starts capturing during half a second and verifies
224 // that recording starts.
225 TEST_F(AudioInputTest, MAYBE_Record) {
226   if (!CanRunAudioTests())
227     return;
228   MakeAudioInputStreamOnAudioThread();
229
230   TestInputCallback test_callback;
231   OpenAndStartAudioInputStreamOnAudioThread(&test_callback);
232
233   message_loop_.PostDelayedTask(
234       FROM_HERE,
235       base::MessageLoop::QuitClosure(),
236       base::TimeDelta::FromMilliseconds(500));
237   message_loop_.Run();
238   EXPECT_GE(test_callback.callback_count(), 2);
239   EXPECT_FALSE(test_callback.had_error());
240
241   StopAndCloseAudioInputStreamOnAudioThread();
242 }
243
244 }  // namespace media