Report errors from ChromiumEnv::GetChildren in Posix.
[chromium-blink-merge.git] / media / audio / audio_manager_unittest.cc
blob4747c2e2996895a219094558d7bb1e0c86fc4b5a
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 "media/audio/audio_manager.h"
9 #include "media/audio/audio_manager_base.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 #if defined(OS_LINUX)
13 #include "media/audio/linux/audio_manager_linux.h"
14 #endif // defined(OS_LINUX)
16 #if defined(OS_WIN)
17 #include "base/win/scoped_com_initializer.h"
18 #include "media/audio/win/audio_manager_win.h"
19 #include "media/audio/win/wavein_input_win.h"
20 #endif
22 #if defined(USE_PULSEAUDIO)
23 #include "media/audio/pulse/audio_manager_pulse.h"
24 #endif // defined(USE_PULSEAUDIO)
26 namespace media {
28 // Test fixture which allows us to override the default enumeration API on
29 // Windows.
30 class AudioManagerTest
31 : public ::testing::Test {
32 protected:
33 AudioManagerTest()
34 : audio_manager_(AudioManager::Create())
35 #if defined(OS_WIN)
36 , com_init_(base::win::ScopedCOMInitializer::kMTA)
37 #endif
41 #if defined(OS_WIN)
42 bool SetMMDeviceEnumeration() {
43 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
44 // Windows Wave is used as default if Windows XP was detected =>
45 // return false since MMDevice is not supported on XP.
46 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
47 return false;
49 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
50 return true;
53 void SetWaveEnumeration() {
54 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
55 amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
58 std::string GetDeviceIdFromPCMWaveInAudioInputStream(
59 const std::string& device_id) {
60 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
61 AudioParameters parameters(
62 AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
63 AudioParameters::kAudioCDSampleRate, 16,
64 1024);
65 scoped_ptr<PCMWaveInAudioInputStream> stream(
66 static_cast<PCMWaveInAudioInputStream*>(
67 amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
68 return stream.get() ? stream->device_id_ : std::string();
70 #endif
72 // Helper method which verifies that the device list starts with a valid
73 // default record followed by non-default device names.
74 static void CheckDeviceNames(const AudioDeviceNames& device_names) {
75 VLOG(2) << "Got " << device_names.size() << " audio devices.";
76 if (!device_names.empty()) {
77 AudioDeviceNames::const_iterator it = device_names.begin();
79 // The first device in the list should always be the default device.
80 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
81 it->device_name);
82 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
83 ++it;
85 // Other devices should have non-empty name and id and should not contain
86 // default name or id.
87 while (it != device_names.end()) {
88 EXPECT_FALSE(it->device_name.empty());
89 EXPECT_FALSE(it->unique_id.empty());
90 VLOG(2) << "Device ID(" << it->unique_id
91 << "), label: " << it->device_name;
92 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName),
93 it->device_name);
94 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId),
95 it->unique_id);
96 ++it;
98 } else {
99 // Log a warning so we can see the status on the build bots. No need to
100 // break the test though since this does successfully test the code and
101 // some failure cases.
102 LOG(WARNING) << "No input devices detected";
106 bool CanRunInputTest() {
107 return audio_manager_->HasAudioInputDevices();
110 bool CanRunOutputTest() {
111 return audio_manager_->HasAudioOutputDevices();
114 scoped_ptr<AudioManager> audio_manager_;
116 #if defined(OS_WIN)
117 // The MMDevice API requires COM to be initialized on the current thread.
118 base::win::ScopedCOMInitializer com_init_;
119 #endif
122 // Test that devices can be enumerated.
123 TEST_F(AudioManagerTest, EnumerateInputDevices) {
124 if (!CanRunInputTest())
125 return;
127 AudioDeviceNames device_names;
128 audio_manager_->GetAudioInputDeviceNames(&device_names);
129 CheckDeviceNames(device_names);
132 // Test that devices can be enumerated.
133 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
134 if (!CanRunOutputTest())
135 return;
137 AudioDeviceNames device_names;
138 audio_manager_->GetAudioOutputDeviceNames(&device_names);
139 CheckDeviceNames(device_names);
142 // Run additional tests for Windows since enumeration can be done using
143 // two different APIs. MMDevice is default for Vista and higher and Wave
144 // is default for XP and lower.
145 #if defined(OS_WIN)
147 // Override default enumeration API and force usage of Windows MMDevice.
148 // This test will only run on Windows Vista and higher.
149 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
150 if (!CanRunInputTest())
151 return;
153 AudioDeviceNames device_names;
154 if (!SetMMDeviceEnumeration()) {
155 // Usage of MMDevice will fail on XP and lower.
156 LOG(WARNING) << "MM device enumeration is not supported.";
157 return;
159 audio_manager_->GetAudioInputDeviceNames(&device_names);
160 CheckDeviceNames(device_names);
163 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
164 if (!CanRunOutputTest())
165 return;
167 AudioDeviceNames device_names;
168 if (!SetMMDeviceEnumeration()) {
169 // Usage of MMDevice will fail on XP and lower.
170 LOG(WARNING) << "MM device enumeration is not supported.";
171 return;
173 audio_manager_->GetAudioOutputDeviceNames(&device_names);
174 CheckDeviceNames(device_names);
177 // Override default enumeration API and force usage of Windows Wave.
178 // This test will run on Windows XP, Windows Vista and Windows 7.
179 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
180 if (!CanRunInputTest())
181 return;
183 AudioDeviceNames device_names;
184 SetWaveEnumeration();
185 audio_manager_->GetAudioInputDeviceNames(&device_names);
186 CheckDeviceNames(device_names);
189 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
190 if (!CanRunOutputTest())
191 return;
193 AudioDeviceNames device_names;
194 SetWaveEnumeration();
195 audio_manager_->GetAudioOutputDeviceNames(&device_names);
196 CheckDeviceNames(device_names);
199 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
200 if (!CanRunInputTest())
201 return;
203 AudioDeviceNames xp_device_names;
204 SetWaveEnumeration();
205 audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
206 CheckDeviceNames(xp_device_names);
208 // Device ID should remain unchanged, including the default device ID.
209 for (AudioDeviceNames::iterator i = xp_device_names.begin();
210 i != xp_device_names.end(); ++i) {
211 EXPECT_EQ(i->unique_id,
212 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
216 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
217 if (!CanRunInputTest())
218 return;
220 if (!SetMMDeviceEnumeration()) {
221 // Usage of MMDevice will fail on XP and lower.
222 LOG(WARNING) << "MM device enumeration is not supported.";
223 return;
226 AudioDeviceNames device_names;
227 audio_manager_->GetAudioInputDeviceNames(&device_names);
228 CheckDeviceNames(device_names);
230 for (AudioDeviceNames::iterator i = device_names.begin();
231 i != device_names.end(); ++i) {
232 std::string converted_id =
233 GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
234 if (i == device_names.begin()) {
235 // The first in the list is the default device ID, which should not be
236 // changed when passed to PCMWaveInAudioInputStream.
237 EXPECT_EQ(i->unique_id, converted_id);
238 } else {
239 // MMDevice-style device IDs should be converted to WaveIn-style device
240 // IDs.
241 EXPECT_NE(i->unique_id, converted_id);
246 #endif // defined(OS_WIN)
248 #if defined(USE_PULSEAUDIO)
249 // On Linux, there are two implementations available and both can
250 // sometimes be tested on a single system. These tests specifically
251 // test Pulseaudio.
253 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
254 if (!CanRunInputTest())
255 return;
257 audio_manager_.reset(AudioManagerPulse::Create());
258 if (audio_manager_.get()) {
259 AudioDeviceNames device_names;
260 audio_manager_->GetAudioInputDeviceNames(&device_names);
261 CheckDeviceNames(device_names);
262 } else {
263 LOG(WARNING) << "No pulseaudio on this system.";
267 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
268 if (!CanRunOutputTest())
269 return;
271 audio_manager_.reset(AudioManagerPulse::Create());
272 if (audio_manager_.get()) {
273 AudioDeviceNames device_names;
274 audio_manager_->GetAudioOutputDeviceNames(&device_names);
275 CheckDeviceNames(device_names);
276 } else {
277 LOG(WARNING) << "No pulseaudio on this system.";
280 #endif // defined(USE_PULSEAUDIO)
282 #if defined(USE_ALSA)
283 // On Linux, there are two implementations available and both can
284 // sometimes be tested on a single system. These tests specifically
285 // test Alsa.
287 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
288 if (!CanRunInputTest())
289 return;
291 VLOG(2) << "Testing AudioManagerLinux.";
292 audio_manager_.reset(new AudioManagerLinux());
293 AudioDeviceNames device_names;
294 audio_manager_->GetAudioInputDeviceNames(&device_names);
295 CheckDeviceNames(device_names);
298 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
299 if (!CanRunOutputTest())
300 return;
302 VLOG(2) << "Testing AudioManagerLinux.";
303 audio_manager_.reset(new AudioManagerLinux());
304 AudioDeviceNames device_names;
305 audio_manager_->GetAudioOutputDeviceNames(&device_names);
306 CheckDeviceNames(device_names);
308 #endif // defined(USE_ALSA)
310 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
311 #if defined(OS_WIN) || defined(OS_MACOSX)
312 if (!CanRunInputTest())
313 return;
315 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
316 EXPECT_TRUE(params.IsValid());
317 #endif // defined(OS_WIN) || defined(OS_MACOSX)
320 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
321 #if defined(OS_WIN) || defined(OS_MACOSX)
322 if (!CanRunInputTest() || !CanRunOutputTest())
323 return;
325 AudioDeviceNames device_names;
326 audio_manager_->GetAudioInputDeviceNames(&device_names);
327 bool found_an_associated_device = false;
328 for (AudioDeviceNames::iterator it = device_names.begin();
329 it != device_names.end();
330 ++it) {
331 EXPECT_FALSE(it->unique_id.empty());
332 EXPECT_FALSE(it->device_name.empty());
333 std::string output_device_id(
334 audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
335 if (!output_device_id.empty()) {
336 VLOG(2) << it->unique_id << " matches with " << output_device_id;
337 found_an_associated_device = true;
341 EXPECT_TRUE(found_an_associated_device);
342 #endif // defined(OS_WIN) || defined(OS_MACOSX)
345 } // namespace media