Roll src/third_party/skia 43315bb:4b195e5
[chromium-blink-merge.git] / media / audio / audio_manager_unittest.cc
blob48bb51cee5c83f15b6909a4988e2f67c173e1209
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/bind.h"
6 #include "base/environment.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "media/audio/audio_manager.h"
11 #include "media/audio/audio_manager_base.h"
12 #include "media/audio/audio_unittest_util.h"
13 #include "media/audio/fake_audio_log_factory.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 #if defined(USE_ALSA)
17 #include "media/audio/alsa/audio_manager_alsa.h"
18 #endif // defined(USE_ALSA)
20 #if defined(OS_WIN)
21 #include "base/win/scoped_com_initializer.h"
22 #include "media/audio/win/audio_manager_win.h"
23 #include "media/audio/win/wavein_input_win.h"
24 #endif
26 #if defined(USE_PULSEAUDIO)
27 #include "media/audio/pulse/audio_manager_pulse.h"
28 #endif // defined(USE_PULSEAUDIO)
30 namespace media {
32 // Test fixture which allows us to override the default enumeration API on
33 // Windows.
34 class AudioManagerTest : public ::testing::Test {
35 protected:
36 AudioManagerTest() : audio_manager_(AudioManager::CreateForTesting()) {
37 // Wait for audio thread initialization to complete. Otherwise the
38 // enumeration type may not have been set yet.
39 base::WaitableEvent event(false, false);
40 audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
41 &base::WaitableEvent::Signal, base::Unretained(&event)));
42 event.Wait();
45 #if defined(OS_WIN)
46 bool SetMMDeviceEnumeration() {
47 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
48 // Windows Wave is used as default if Windows XP was detected =>
49 // return false since MMDevice is not supported on XP.
50 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
51 return false;
53 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
54 return true;
57 void SetWaveEnumeration() {
58 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
59 amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
62 std::string GetDeviceIdFromPCMWaveInAudioInputStream(
63 const std::string& device_id) {
64 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
65 AudioParameters parameters(
66 AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
67 AudioParameters::kAudioCDSampleRate, 16,
68 1024);
69 scoped_ptr<PCMWaveInAudioInputStream> stream(
70 static_cast<PCMWaveInAudioInputStream*>(
71 amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
72 return stream.get() ? stream->device_id_ : std::string();
74 #endif
76 // Helper method which verifies that the device list starts with a valid
77 // default record followed by non-default device names.
78 static void CheckDeviceNames(const AudioDeviceNames& device_names) {
79 DVLOG(2) << "Got " << device_names.size() << " audio devices.";
80 if (!device_names.empty()) {
81 AudioDeviceNames::const_iterator it = device_names.begin();
83 // The first device in the list should always be the default device.
84 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
85 it->device_name);
86 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
87 ++it;
89 // Other devices should have non-empty name and id and should not contain
90 // default name or id.
91 while (it != device_names.end()) {
92 EXPECT_FALSE(it->device_name.empty());
93 EXPECT_FALSE(it->unique_id.empty());
94 DVLOG(2) << "Device ID(" << it->unique_id
95 << "), label: " << it->device_name;
96 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName),
97 it->device_name);
98 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId),
99 it->unique_id);
100 ++it;
102 } else {
103 // Log a warning so we can see the status on the build bots. No need to
104 // break the test though since this does successfully test the code and
105 // some failure cases.
106 LOG(WARNING) << "No input devices detected";
110 bool InputDevicesAvailable() {
111 return audio_manager_->HasAudioInputDevices();
114 bool OutputDevicesAvailable() {
115 return audio_manager_->HasAudioOutputDevices();
118 #if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
119 template <class T>
120 void CreateAudioManagerForTesting() {
121 // Only one AudioManager may exist at a time, so destroy the one we're
122 // currently holding before creating a new one.
123 audio_manager_.reset();
124 audio_manager_.reset(T::Create(&fake_audio_log_factory_));
126 #endif
128 // Synchronously runs the provided callback/closure on the audio thread.
129 void RunOnAudioThread(const base::Closure& closure) {
130 if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) {
131 base::WaitableEvent event(false, false);
132 audio_manager_->GetTaskRunner()->PostTask(
133 FROM_HERE,
134 base::Bind(&AudioManagerTest::RunOnAudioThreadImpl,
135 base::Unretained(this),
136 closure,
137 &event));
138 event.Wait();
139 } else {
140 closure.Run();
144 void RunOnAudioThreadImpl(const base::Closure& closure,
145 base::WaitableEvent* event) {
146 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
147 closure.Run();
148 event->Signal();
151 FakeAudioLogFactory fake_audio_log_factory_;
152 scoped_ptr<AudioManager> audio_manager_;
155 // Test that devices can be enumerated.
156 TEST_F(AudioManagerTest, EnumerateInputDevices) {
157 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
159 AudioDeviceNames device_names;
160 RunOnAudioThread(
161 base::Bind(&AudioManager::GetAudioInputDeviceNames,
162 base::Unretained(audio_manager_.get()),
163 &device_names));
164 CheckDeviceNames(device_names);
167 // Test that devices can be enumerated.
168 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
169 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
171 AudioDeviceNames device_names;
172 RunOnAudioThread(
173 base::Bind(&AudioManager::GetAudioOutputDeviceNames,
174 base::Unretained(audio_manager_.get()),
175 &device_names));
176 CheckDeviceNames(device_names);
179 // Run additional tests for Windows since enumeration can be done using
180 // two different APIs. MMDevice is default for Vista and higher and Wave
181 // is default for XP and lower.
182 #if defined(OS_WIN)
184 // Override default enumeration API and force usage of Windows MMDevice.
185 // This test will only run on Windows Vista and higher.
186 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
187 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
189 AudioDeviceNames device_names;
190 if (!SetMMDeviceEnumeration()) {
191 // Usage of MMDevice will fail on XP and lower.
192 LOG(WARNING) << "MM device enumeration is not supported.";
193 return;
195 audio_manager_->GetAudioInputDeviceNames(&device_names);
196 CheckDeviceNames(device_names);
199 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
200 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
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_->GetAudioOutputDeviceNames(&device_names);
209 CheckDeviceNames(device_names);
212 // Override default enumeration API and force usage of Windows Wave.
213 // This test will run on Windows XP, Windows Vista and Windows 7.
214 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
215 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
217 AudioDeviceNames device_names;
218 SetWaveEnumeration();
219 audio_manager_->GetAudioInputDeviceNames(&device_names);
220 CheckDeviceNames(device_names);
223 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
224 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
226 AudioDeviceNames device_names;
227 SetWaveEnumeration();
228 audio_manager_->GetAudioOutputDeviceNames(&device_names);
229 CheckDeviceNames(device_names);
232 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
233 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
235 AudioDeviceNames xp_device_names;
236 SetWaveEnumeration();
237 audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
238 CheckDeviceNames(xp_device_names);
240 // Device ID should remain unchanged, including the default device ID.
241 for (AudioDeviceNames::iterator i = xp_device_names.begin();
242 i != xp_device_names.end(); ++i) {
243 EXPECT_EQ(i->unique_id,
244 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
248 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
249 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
251 if (!SetMMDeviceEnumeration()) {
252 // Usage of MMDevice will fail on XP and lower.
253 LOG(WARNING) << "MM device enumeration is not supported.";
254 return;
257 AudioDeviceNames device_names;
258 audio_manager_->GetAudioInputDeviceNames(&device_names);
259 CheckDeviceNames(device_names);
261 for (AudioDeviceNames::iterator i = device_names.begin();
262 i != device_names.end(); ++i) {
263 std::string converted_id =
264 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
265 if (i == device_names.begin()) {
266 // The first in the list is the default device ID, which should not be
267 // changed when passed to PCMWaveInAudioInputStream.
268 EXPECT_EQ(i->unique_id, converted_id);
269 } else {
270 // MMDevice-style device IDs should be converted to WaveIn-style device
271 // IDs.
272 EXPECT_NE(i->unique_id, converted_id);
277 #endif // defined(OS_WIN)
279 #if defined(USE_PULSEAUDIO)
280 // On Linux, there are two implementations available and both can
281 // sometimes be tested on a single system. These tests specifically
282 // test Pulseaudio.
284 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
285 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
287 CreateAudioManagerForTesting<AudioManagerPulse>();
288 if (audio_manager_.get()) {
289 AudioDeviceNames device_names;
290 audio_manager_->GetAudioInputDeviceNames(&device_names);
291 CheckDeviceNames(device_names);
292 } else {
293 LOG(WARNING) << "No pulseaudio on this system.";
297 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
298 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
300 CreateAudioManagerForTesting<AudioManagerPulse>();
301 if (audio_manager_.get()) {
302 AudioDeviceNames device_names;
303 audio_manager_->GetAudioOutputDeviceNames(&device_names);
304 CheckDeviceNames(device_names);
305 } else {
306 LOG(WARNING) << "No pulseaudio on this system.";
309 #endif // defined(USE_PULSEAUDIO)
311 #if defined(USE_ALSA)
312 // On Linux, there are two implementations available and both can
313 // sometimes be tested on a single system. These tests specifically
314 // test Alsa.
316 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
317 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
319 DVLOG(2) << "Testing AudioManagerAlsa.";
320 CreateAudioManagerForTesting<AudioManagerAlsa>();
321 AudioDeviceNames device_names;
322 audio_manager_->GetAudioInputDeviceNames(&device_names);
323 CheckDeviceNames(device_names);
326 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
327 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
329 DVLOG(2) << "Testing AudioManagerAlsa.";
330 CreateAudioManagerForTesting<AudioManagerAlsa>();
331 AudioDeviceNames device_names;
332 audio_manager_->GetAudioOutputDeviceNames(&device_names);
333 CheckDeviceNames(device_names);
335 #endif // defined(USE_ALSA)
337 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
338 #if defined(OS_WIN) || defined(OS_MACOSX)
339 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
341 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
342 EXPECT_TRUE(params.IsValid());
343 #endif // defined(OS_WIN) || defined(OS_MACOSX)
346 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
347 #if defined(OS_WIN) || defined(OS_MACOSX)
348 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
350 AudioDeviceNames device_names;
351 audio_manager_->GetAudioInputDeviceNames(&device_names);
352 bool found_an_associated_device = false;
353 for (AudioDeviceNames::iterator it = device_names.begin();
354 it != device_names.end();
355 ++it) {
356 EXPECT_FALSE(it->unique_id.empty());
357 EXPECT_FALSE(it->device_name.empty());
358 std::string output_device_id(
359 audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
360 if (!output_device_id.empty()) {
361 DVLOG(2) << it->unique_id << " matches with " << output_device_id;
362 found_an_associated_device = true;
366 EXPECT_TRUE(found_an_associated_device);
367 #endif // defined(OS_WIN) || defined(OS_MACOSX)
370 } // namespace media