Revert of Enabling audio quality test on mac. (patchset #1 id:1 of https://codereview...
[chromium-blink-merge.git] / media / audio / audio_manager_unittest.cc
blob902618ebd9233da945595884465b2e8e7a7dddf6
1 // Copyright 2013 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/environment.h"
6 #include "base/logging.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "media/audio/audio_manager.h"
10 #include "media/audio/audio_manager_base.h"
11 #include "media/audio/fake_audio_log_factory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 #if defined(USE_ALSA)
15 #include "media/audio/alsa/audio_manager_alsa.h"
16 #endif // defined(USE_ALSA)
18 #if defined(OS_WIN)
19 #include "base/win/scoped_com_initializer.h"
20 #include "media/audio/win/audio_manager_win.h"
21 #include "media/audio/win/wavein_input_win.h"
22 #endif
24 #if defined(USE_PULSEAUDIO)
25 #include "media/audio/pulse/audio_manager_pulse.h"
26 #endif // defined(USE_PULSEAUDIO)
28 namespace media {
30 // Test fixture which allows us to override the default enumeration API on
31 // Windows.
32 class AudioManagerTest : public ::testing::Test {
33 protected:
34 AudioManagerTest()
35 : audio_manager_(AudioManager::CreateForTesting())
36 #if defined(OS_WIN)
37 , com_init_(base::win::ScopedCOMInitializer::kMTA)
38 #endif
40 // Wait for audio thread initialization to complete. Otherwise the
41 // enumeration type may not have been set yet.
42 base::WaitableEvent event(false, false);
43 audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
44 &base::WaitableEvent::Signal, base::Unretained(&event)));
45 event.Wait();
48 AudioManager* audio_manager() { return audio_manager_.get(); };
50 #if defined(OS_WIN)
51 bool SetMMDeviceEnumeration() {
52 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
53 // Windows Wave is used as default if Windows XP was detected =>
54 // return false since MMDevice is not supported on XP.
55 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
56 return false;
58 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
59 return true;
62 void SetWaveEnumeration() {
63 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
64 amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
67 std::string GetDeviceIdFromPCMWaveInAudioInputStream(
68 const std::string& device_id) {
69 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
70 AudioParameters parameters(
71 AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
72 AudioParameters::kAudioCDSampleRate, 16,
73 1024);
74 scoped_ptr<PCMWaveInAudioInputStream> stream(
75 static_cast<PCMWaveInAudioInputStream*>(
76 amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
77 return stream.get() ? stream->device_id_ : std::string();
79 #endif
81 // Helper method which verifies that the device list starts with a valid
82 // default record followed by non-default device names.
83 static void CheckDeviceNames(const AudioDeviceNames& device_names) {
84 VLOG(2) << "Got " << device_names.size() << " audio devices.";
85 if (!device_names.empty()) {
86 AudioDeviceNames::const_iterator it = device_names.begin();
88 // The first device in the list should always be the default device.
89 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
90 it->device_name);
91 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
92 ++it;
94 // Other devices should have non-empty name and id and should not contain
95 // default name or id.
96 while (it != device_names.end()) {
97 EXPECT_FALSE(it->device_name.empty());
98 EXPECT_FALSE(it->unique_id.empty());
99 VLOG(2) << "Device ID(" << it->unique_id
100 << "), label: " << it->device_name;
101 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName),
102 it->device_name);
103 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId),
104 it->unique_id);
105 ++it;
107 } else {
108 // Log a warning so we can see the status on the build bots. No need to
109 // break the test though since this does successfully test the code and
110 // some failure cases.
111 LOG(WARNING) << "No input devices detected";
115 bool CanRunInputTest() {
116 return audio_manager_->HasAudioInputDevices();
119 bool CanRunOutputTest() {
120 return audio_manager_->HasAudioOutputDevices();
123 #if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
124 template <class T>
125 void CreateAudioManagerForTesting() {
126 // Only one AudioManager may exist at a time, so destroy the one we're
127 // currently holding before creating a new one.
128 audio_manager_.reset();
129 audio_manager_.reset(T::Create(&fake_audio_log_factory_));
131 #endif
133 // Synchronously runs the provided callback/closure on the audio thread.
134 void RunOnAudioThread(const base::Closure& closure) {
135 if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) {
136 base::WaitableEvent event(false, false);
137 audio_manager_->GetTaskRunner()->PostTask(
138 FROM_HERE,
139 base::Bind(&AudioManagerTest::RunOnAudioThreadImpl,
140 base::Unretained(this),
141 closure,
142 &event));
143 event.Wait();
144 } else {
145 closure.Run();
149 void RunOnAudioThreadImpl(const base::Closure& closure,
150 base::WaitableEvent* event) {
151 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
152 closure.Run();
153 event->Signal();
156 FakeAudioLogFactory fake_audio_log_factory_;
157 scoped_ptr<AudioManager> audio_manager_;
159 #if defined(OS_WIN)
160 // The MMDevice API requires COM to be initialized on the current thread.
161 base::win::ScopedCOMInitializer com_init_;
162 #endif
165 // Test that devices can be enumerated.
166 TEST_F(AudioManagerTest, EnumerateInputDevices) {
167 if (!CanRunInputTest())
168 return;
170 AudioDeviceNames device_names;
171 RunOnAudioThread(
172 base::Bind(&AudioManager::GetAudioInputDeviceNames,
173 base::Unretained(audio_manager()),
174 &device_names));
175 CheckDeviceNames(device_names);
178 // Test that devices can be enumerated.
179 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
180 if (!CanRunOutputTest())
181 return;
183 AudioDeviceNames device_names;
184 RunOnAudioThread(
185 base::Bind(&AudioManager::GetAudioOutputDeviceNames,
186 base::Unretained(audio_manager()),
187 &device_names));
188 CheckDeviceNames(device_names);
191 // Run additional tests for Windows since enumeration can be done using
192 // two different APIs. MMDevice is default for Vista and higher and Wave
193 // is default for XP and lower.
194 #if defined(OS_WIN)
196 // Override default enumeration API and force usage of Windows MMDevice.
197 // This test will only run on Windows Vista and higher.
198 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
199 if (!CanRunInputTest())
200 return;
202 AudioDeviceNames device_names;
203 if (!SetMMDeviceEnumeration()) {
204 // Usage of MMDevice will fail on XP and lower.
205 LOG(WARNING) << "MM device enumeration is not supported.";
206 return;
208 audio_manager_->GetAudioInputDeviceNames(&device_names);
209 CheckDeviceNames(device_names);
212 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
213 if (!CanRunOutputTest())
214 return;
216 AudioDeviceNames device_names;
217 if (!SetMMDeviceEnumeration()) {
218 // Usage of MMDevice will fail on XP and lower.
219 LOG(WARNING) << "MM device enumeration is not supported.";
220 return;
222 audio_manager_->GetAudioOutputDeviceNames(&device_names);
223 CheckDeviceNames(device_names);
226 // Override default enumeration API and force usage of Windows Wave.
227 // This test will run on Windows XP, Windows Vista and Windows 7.
228 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
229 if (!CanRunInputTest())
230 return;
232 AudioDeviceNames device_names;
233 SetWaveEnumeration();
234 audio_manager_->GetAudioInputDeviceNames(&device_names);
235 CheckDeviceNames(device_names);
238 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
239 if (!CanRunOutputTest())
240 return;
242 AudioDeviceNames device_names;
243 SetWaveEnumeration();
244 audio_manager_->GetAudioOutputDeviceNames(&device_names);
245 CheckDeviceNames(device_names);
248 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
249 if (!CanRunInputTest())
250 return;
252 AudioDeviceNames xp_device_names;
253 SetWaveEnumeration();
254 audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
255 CheckDeviceNames(xp_device_names);
257 // Device ID should remain unchanged, including the default device ID.
258 for (AudioDeviceNames::iterator i = xp_device_names.begin();
259 i != xp_device_names.end(); ++i) {
260 EXPECT_EQ(i->unique_id,
261 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
265 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
266 if (!CanRunInputTest())
267 return;
269 if (!SetMMDeviceEnumeration()) {
270 // Usage of MMDevice will fail on XP and lower.
271 LOG(WARNING) << "MM device enumeration is not supported.";
272 return;
275 AudioDeviceNames device_names;
276 audio_manager_->GetAudioInputDeviceNames(&device_names);
277 CheckDeviceNames(device_names);
279 for (AudioDeviceNames::iterator i = device_names.begin();
280 i != device_names.end(); ++i) {
281 std::string converted_id =
282 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
283 if (i == device_names.begin()) {
284 // The first in the list is the default device ID, which should not be
285 // changed when passed to PCMWaveInAudioInputStream.
286 EXPECT_EQ(i->unique_id, converted_id);
287 } else {
288 // MMDevice-style device IDs should be converted to WaveIn-style device
289 // IDs.
290 EXPECT_NE(i->unique_id, converted_id);
295 #endif // defined(OS_WIN)
297 #if defined(USE_PULSEAUDIO)
298 // On Linux, there are two implementations available and both can
299 // sometimes be tested on a single system. These tests specifically
300 // test Pulseaudio.
302 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
303 if (!CanRunInputTest())
304 return;
306 CreateAudioManagerForTesting<AudioManagerPulse>();
307 if (audio_manager_.get()) {
308 AudioDeviceNames device_names;
309 audio_manager_->GetAudioInputDeviceNames(&device_names);
310 CheckDeviceNames(device_names);
311 } else {
312 LOG(WARNING) << "No pulseaudio on this system.";
316 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
317 if (!CanRunOutputTest())
318 return;
320 CreateAudioManagerForTesting<AudioManagerPulse>();
321 if (audio_manager_.get()) {
322 AudioDeviceNames device_names;
323 audio_manager_->GetAudioOutputDeviceNames(&device_names);
324 CheckDeviceNames(device_names);
325 } else {
326 LOG(WARNING) << "No pulseaudio on this system.";
329 #endif // defined(USE_PULSEAUDIO)
331 #if defined(USE_ALSA)
332 // On Linux, there are two implementations available and both can
333 // sometimes be tested on a single system. These tests specifically
334 // test Alsa.
336 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
337 if (!CanRunInputTest())
338 return;
340 VLOG(2) << "Testing AudioManagerAlsa.";
341 CreateAudioManagerForTesting<AudioManagerAlsa>();
342 AudioDeviceNames device_names;
343 audio_manager_->GetAudioInputDeviceNames(&device_names);
344 CheckDeviceNames(device_names);
347 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
348 if (!CanRunOutputTest())
349 return;
351 VLOG(2) << "Testing AudioManagerAlsa.";
352 CreateAudioManagerForTesting<AudioManagerAlsa>();
353 AudioDeviceNames device_names;
354 audio_manager_->GetAudioOutputDeviceNames(&device_names);
355 CheckDeviceNames(device_names);
357 #endif // defined(USE_ALSA)
359 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
360 #if defined(OS_WIN) || defined(OS_MACOSX)
361 if (!CanRunInputTest())
362 return;
364 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
365 EXPECT_TRUE(params.IsValid());
366 #endif // defined(OS_WIN) || defined(OS_MACOSX)
369 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
370 #if defined(OS_WIN) || defined(OS_MACOSX)
371 if (!CanRunInputTest() || !CanRunOutputTest())
372 return;
374 AudioDeviceNames device_names;
375 audio_manager_->GetAudioInputDeviceNames(&device_names);
376 bool found_an_associated_device = false;
377 for (AudioDeviceNames::iterator it = device_names.begin();
378 it != device_names.end();
379 ++it) {
380 EXPECT_FALSE(it->unique_id.empty());
381 EXPECT_FALSE(it->device_name.empty());
382 std::string output_device_id(
383 audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
384 if (!output_device_id.empty()) {
385 VLOG(2) << it->unique_id << " matches with " << output_device_id;
386 found_an_associated_device = true;
390 EXPECT_TRUE(found_an_associated_device);
391 #endif // defined(OS_WIN) || defined(OS_MACOSX)
394 } // namespace media