Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / media / audio / audio_manager_unittest.cc
blobe876dd173759517168a93767bcd5ff673f438a9e
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()) {}
38 #if defined(OS_WIN)
39 bool SetMMDeviceEnumeration() {
40 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
41 // Windows Wave is used as default if Windows XP was detected =>
42 // return false since MMDevice is not supported on XP.
43 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
44 return false;
46 amw->set_enumeration_type(AudioManagerWin::kMMDeviceEnumeration);
47 return true;
50 void SetWaveEnumeration() {
51 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
52 amw->set_enumeration_type(AudioManagerWin::kWaveEnumeration);
55 std::string GetDeviceIdFromPCMWaveInAudioInputStream(
56 const std::string& device_id) {
57 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
58 AudioParameters parameters(
59 AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
60 AudioParameters::kAudioCDSampleRate, 16,
61 1024);
62 scoped_ptr<PCMWaveInAudioInputStream> stream(
63 static_cast<PCMWaveInAudioInputStream*>(
64 amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
65 return stream.get() ? stream->device_id_ : std::string();
67 #endif
69 // Helper method which verifies that the device list starts with a valid
70 // default record followed by non-default device names.
71 static void CheckDeviceNames(const AudioDeviceNames& device_names) {
72 DVLOG(2) << "Got " << device_names.size() << " audio devices.";
73 if (!device_names.empty()) {
74 AudioDeviceNames::const_iterator it = device_names.begin();
76 // The first device in the list should always be the default device.
77 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
78 it->device_name);
79 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
80 ++it;
82 // Other devices should have non-empty name and id and should not contain
83 // default name or id.
84 while (it != device_names.end()) {
85 EXPECT_FALSE(it->device_name.empty());
86 EXPECT_FALSE(it->unique_id.empty());
87 DVLOG(2) << "Device ID(" << it->unique_id
88 << "), label: " << it->device_name;
89 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName),
90 it->device_name);
91 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId),
92 it->unique_id);
93 ++it;
95 } else {
96 // Log a warning so we can see the status on the build bots. No need to
97 // break the test though since this does successfully test the code and
98 // some failure cases.
99 LOG(WARNING) << "No input devices detected";
103 bool InputDevicesAvailable() {
104 return audio_manager_->HasAudioInputDevices();
107 bool OutputDevicesAvailable() {
108 return audio_manager_->HasAudioOutputDevices();
111 #if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
112 template <class T>
113 void CreateAudioManagerForTesting() {
114 // Only one AudioManager may exist at a time, so destroy the one we're
115 // currently holding before creating a new one.
116 audio_manager_.reset();
117 audio_manager_.reset(T::Create(&fake_audio_log_factory_));
119 #endif
121 // Synchronously runs the provided callback/closure on the audio thread.
122 void RunOnAudioThread(const base::Closure& closure) {
123 if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) {
124 base::WaitableEvent event(false, false);
125 audio_manager_->GetTaskRunner()->PostTask(
126 FROM_HERE,
127 base::Bind(&AudioManagerTest::RunOnAudioThreadImpl,
128 base::Unretained(this),
129 closure,
130 &event));
131 event.Wait();
132 } else {
133 closure.Run();
137 void RunOnAudioThreadImpl(const base::Closure& closure,
138 base::WaitableEvent* event) {
139 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
140 closure.Run();
141 event->Signal();
144 FakeAudioLogFactory fake_audio_log_factory_;
145 scoped_ptr<AudioManager> audio_manager_;
147 #if defined(OS_WIN)
148 // The MMDevice API requires COM to be initialized on the current thread.
149 base::win::ScopedCOMInitializer com_init_;
150 #endif
153 // Test that devices can be enumerated.
154 TEST_F(AudioManagerTest, EnumerateInputDevices) {
155 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
157 AudioDeviceNames device_names;
158 RunOnAudioThread(
159 base::Bind(&AudioManager::GetAudioInputDeviceNames,
160 base::Unretained(audio_manager_.get()),
161 &device_names));
162 CheckDeviceNames(device_names);
165 // Test that devices can be enumerated.
166 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
167 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
169 AudioDeviceNames device_names;
170 RunOnAudioThread(
171 base::Bind(&AudioManager::GetAudioOutputDeviceNames,
172 base::Unretained(audio_manager_.get()),
173 &device_names));
174 CheckDeviceNames(device_names);
177 // Run additional tests for Windows since enumeration can be done using
178 // two different APIs. MMDevice is default for Vista and higher and Wave
179 // is default for XP and lower.
180 #if defined(OS_WIN)
182 // Override default enumeration API and force usage of Windows MMDevice.
183 // This test will only run on Windows Vista and higher.
184 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
185 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
187 AudioDeviceNames device_names;
188 if (!SetMMDeviceEnumeration()) {
189 // Usage of MMDevice will fail on XP and lower.
190 LOG(WARNING) << "MM device enumeration is not supported.";
191 return;
193 audio_manager_->GetAudioInputDeviceNames(&device_names);
194 CheckDeviceNames(device_names);
197 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
198 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
200 AudioDeviceNames device_names;
201 if (!SetMMDeviceEnumeration()) {
202 // Usage of MMDevice will fail on XP and lower.
203 LOG(WARNING) << "MM device enumeration is not supported.";
204 return;
206 audio_manager_->GetAudioOutputDeviceNames(&device_names);
207 CheckDeviceNames(device_names);
210 // Override default enumeration API and force usage of Windows Wave.
211 // This test will run on Windows XP, Windows Vista and Windows 7.
212 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
213 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
215 AudioDeviceNames device_names;
216 SetWaveEnumeration();
217 audio_manager_->GetAudioInputDeviceNames(&device_names);
218 CheckDeviceNames(device_names);
221 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
222 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
224 AudioDeviceNames device_names;
225 SetWaveEnumeration();
226 audio_manager_->GetAudioOutputDeviceNames(&device_names);
227 CheckDeviceNames(device_names);
230 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
231 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
233 AudioDeviceNames xp_device_names;
234 SetWaveEnumeration();
235 audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
236 CheckDeviceNames(xp_device_names);
238 // Device ID should remain unchanged, including the default device ID.
239 for (AudioDeviceNames::iterator i = xp_device_names.begin();
240 i != xp_device_names.end(); ++i) {
241 EXPECT_EQ(i->unique_id,
242 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
246 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
247 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
249 if (!SetMMDeviceEnumeration()) {
250 // Usage of MMDevice will fail on XP and lower.
251 LOG(WARNING) << "MM device enumeration is not supported.";
252 return;
255 AudioDeviceNames device_names;
256 audio_manager_->GetAudioInputDeviceNames(&device_names);
257 CheckDeviceNames(device_names);
259 for (AudioDeviceNames::iterator i = device_names.begin();
260 i != device_names.end(); ++i) {
261 std::string converted_id =
262 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
263 if (i == device_names.begin()) {
264 // The first in the list is the default device ID, which should not be
265 // changed when passed to PCMWaveInAudioInputStream.
266 EXPECT_EQ(i->unique_id, converted_id);
267 } else {
268 // MMDevice-style device IDs should be converted to WaveIn-style device
269 // IDs.
270 EXPECT_NE(i->unique_id, converted_id);
275 #endif // defined(OS_WIN)
277 #if defined(USE_PULSEAUDIO)
278 // On Linux, there are two implementations available and both can
279 // sometimes be tested on a single system. These tests specifically
280 // test Pulseaudio.
282 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
283 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
285 CreateAudioManagerForTesting<AudioManagerPulse>();
286 if (audio_manager_.get()) {
287 AudioDeviceNames device_names;
288 audio_manager_->GetAudioInputDeviceNames(&device_names);
289 CheckDeviceNames(device_names);
290 } else {
291 LOG(WARNING) << "No pulseaudio on this system.";
295 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
296 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
298 CreateAudioManagerForTesting<AudioManagerPulse>();
299 if (audio_manager_.get()) {
300 AudioDeviceNames device_names;
301 audio_manager_->GetAudioOutputDeviceNames(&device_names);
302 CheckDeviceNames(device_names);
303 } else {
304 LOG(WARNING) << "No pulseaudio on this system.";
307 #endif // defined(USE_PULSEAUDIO)
309 #if defined(USE_ALSA)
310 // On Linux, there are two implementations available and both can
311 // sometimes be tested on a single system. These tests specifically
312 // test Alsa.
314 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
315 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
317 DVLOG(2) << "Testing AudioManagerAlsa.";
318 CreateAudioManagerForTesting<AudioManagerAlsa>();
319 AudioDeviceNames device_names;
320 audio_manager_->GetAudioInputDeviceNames(&device_names);
321 CheckDeviceNames(device_names);
324 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
325 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
327 DVLOG(2) << "Testing AudioManagerAlsa.";
328 CreateAudioManagerForTesting<AudioManagerAlsa>();
329 AudioDeviceNames device_names;
330 audio_manager_->GetAudioOutputDeviceNames(&device_names);
331 CheckDeviceNames(device_names);
333 #endif // defined(USE_ALSA)
335 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
336 #if defined(OS_WIN) || defined(OS_MACOSX)
337 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
339 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
340 EXPECT_TRUE(params.IsValid());
341 #endif // defined(OS_WIN) || defined(OS_MACOSX)
344 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
345 #if defined(OS_WIN) || defined(OS_MACOSX)
346 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
348 AudioDeviceNames device_names;
349 audio_manager_->GetAudioInputDeviceNames(&device_names);
350 bool found_an_associated_device = false;
351 for (AudioDeviceNames::iterator it = device_names.begin();
352 it != device_names.end();
353 ++it) {
354 EXPECT_FALSE(it->unique_id.empty());
355 EXPECT_FALSE(it->device_name.empty());
356 std::string output_device_id(
357 audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
358 if (!output_device_id.empty()) {
359 DVLOG(2) << it->unique_id << " matches with " << output_device_id;
360 found_an_associated_device = true;
364 EXPECT_TRUE(found_an_associated_device);
365 #endif // defined(OS_WIN) || defined(OS_MACOSX)
368 } // namespace media