Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / media / audio / audio_manager_unittest.cc
blob26c110e3adef7202d88c34806543b47f32e349ec
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()
37 : audio_manager_(AudioManager::CreateForTesting())
38 #if defined(OS_WIN)
39 , com_init_(base::win::ScopedCOMInitializer::kMTA)
40 #endif
42 // Wait for audio thread initialization to complete. Otherwise the
43 // enumeration type may not have been set yet.
44 base::WaitableEvent event(false, false);
45 audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
46 &base::WaitableEvent::Signal, base::Unretained(&event)));
47 event.Wait();
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 DVLOG(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 DVLOG(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 InputDevicesAvailable() {
116 return audio_manager_->HasAudioInputDevices();
119 bool OutputDevicesAvailable() {
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 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
169 AudioDeviceNames device_names;
170 RunOnAudioThread(
171 base::Bind(&AudioManager::GetAudioInputDeviceNames,
172 base::Unretained(audio_manager_.get()),
173 &device_names));
174 CheckDeviceNames(device_names);
177 // Test that devices can be enumerated.
178 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
179 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
181 AudioDeviceNames device_names;
182 RunOnAudioThread(
183 base::Bind(&AudioManager::GetAudioOutputDeviceNames,
184 base::Unretained(audio_manager_.get()),
185 &device_names));
186 CheckDeviceNames(device_names);
189 // Run additional tests for Windows since enumeration can be done using
190 // two different APIs. MMDevice is default for Vista and higher and Wave
191 // is default for XP and lower.
192 #if defined(OS_WIN)
194 // Override default enumeration API and force usage of Windows MMDevice.
195 // This test will only run on Windows Vista and higher.
196 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
197 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
199 AudioDeviceNames device_names;
200 if (!SetMMDeviceEnumeration()) {
201 // Usage of MMDevice will fail on XP and lower.
202 LOG(WARNING) << "MM device enumeration is not supported.";
203 return;
205 audio_manager_->GetAudioInputDeviceNames(&device_names);
206 CheckDeviceNames(device_names);
209 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
210 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
212 AudioDeviceNames device_names;
213 if (!SetMMDeviceEnumeration()) {
214 // Usage of MMDevice will fail on XP and lower.
215 LOG(WARNING) << "MM device enumeration is not supported.";
216 return;
218 audio_manager_->GetAudioOutputDeviceNames(&device_names);
219 CheckDeviceNames(device_names);
222 // Override default enumeration API and force usage of Windows Wave.
223 // This test will run on Windows XP, Windows Vista and Windows 7.
224 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
225 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
227 AudioDeviceNames device_names;
228 SetWaveEnumeration();
229 audio_manager_->GetAudioInputDeviceNames(&device_names);
230 CheckDeviceNames(device_names);
233 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
234 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
236 AudioDeviceNames device_names;
237 SetWaveEnumeration();
238 audio_manager_->GetAudioOutputDeviceNames(&device_names);
239 CheckDeviceNames(device_names);
242 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
243 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
245 AudioDeviceNames xp_device_names;
246 SetWaveEnumeration();
247 audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
248 CheckDeviceNames(xp_device_names);
250 // Device ID should remain unchanged, including the default device ID.
251 for (AudioDeviceNames::iterator i = xp_device_names.begin();
252 i != xp_device_names.end(); ++i) {
253 EXPECT_EQ(i->unique_id,
254 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
258 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
259 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
261 if (!SetMMDeviceEnumeration()) {
262 // Usage of MMDevice will fail on XP and lower.
263 LOG(WARNING) << "MM device enumeration is not supported.";
264 return;
267 AudioDeviceNames device_names;
268 audio_manager_->GetAudioInputDeviceNames(&device_names);
269 CheckDeviceNames(device_names);
271 for (AudioDeviceNames::iterator i = device_names.begin();
272 i != device_names.end(); ++i) {
273 std::string converted_id =
274 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
275 if (i == device_names.begin()) {
276 // The first in the list is the default device ID, which should not be
277 // changed when passed to PCMWaveInAudioInputStream.
278 EXPECT_EQ(i->unique_id, converted_id);
279 } else {
280 // MMDevice-style device IDs should be converted to WaveIn-style device
281 // IDs.
282 EXPECT_NE(i->unique_id, converted_id);
287 #endif // defined(OS_WIN)
289 #if defined(USE_PULSEAUDIO)
290 // On Linux, there are two implementations available and both can
291 // sometimes be tested on a single system. These tests specifically
292 // test Pulseaudio.
294 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
295 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
297 CreateAudioManagerForTesting<AudioManagerPulse>();
298 if (audio_manager_.get()) {
299 AudioDeviceNames device_names;
300 audio_manager_->GetAudioInputDeviceNames(&device_names);
301 CheckDeviceNames(device_names);
302 } else {
303 LOG(WARNING) << "No pulseaudio on this system.";
307 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
308 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
310 CreateAudioManagerForTesting<AudioManagerPulse>();
311 if (audio_manager_.get()) {
312 AudioDeviceNames device_names;
313 audio_manager_->GetAudioOutputDeviceNames(&device_names);
314 CheckDeviceNames(device_names);
315 } else {
316 LOG(WARNING) << "No pulseaudio on this system.";
319 #endif // defined(USE_PULSEAUDIO)
321 #if defined(USE_ALSA)
322 // On Linux, there are two implementations available and both can
323 // sometimes be tested on a single system. These tests specifically
324 // test Alsa.
326 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
327 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
329 DVLOG(2) << "Testing AudioManagerAlsa.";
330 CreateAudioManagerForTesting<AudioManagerAlsa>();
331 AudioDeviceNames device_names;
332 audio_manager_->GetAudioInputDeviceNames(&device_names);
333 CheckDeviceNames(device_names);
336 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
337 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
339 DVLOG(2) << "Testing AudioManagerAlsa.";
340 CreateAudioManagerForTesting<AudioManagerAlsa>();
341 AudioDeviceNames device_names;
342 audio_manager_->GetAudioOutputDeviceNames(&device_names);
343 CheckDeviceNames(device_names);
345 #endif // defined(USE_ALSA)
347 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
348 #if defined(OS_WIN) || defined(OS_MACOSX)
349 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
351 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
352 EXPECT_TRUE(params.IsValid());
353 #endif // defined(OS_WIN) || defined(OS_MACOSX)
356 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
357 #if defined(OS_WIN) || defined(OS_MACOSX)
358 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
360 AudioDeviceNames device_names;
361 audio_manager_->GetAudioInputDeviceNames(&device_names);
362 bool found_an_associated_device = false;
363 for (AudioDeviceNames::iterator it = device_names.begin();
364 it != device_names.end();
365 ++it) {
366 EXPECT_FALSE(it->unique_id.empty());
367 EXPECT_FALSE(it->device_name.empty());
368 std::string output_device_id(
369 audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
370 if (!output_device_id.empty()) {
371 DVLOG(2) << it->unique_id << " matches with " << output_device_id;
372 found_an_associated_device = true;
376 EXPECT_TRUE(found_an_associated_device);
377 #endif // defined(OS_WIN) || defined(OS_MACOSX)
380 } // namespace media