OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
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" | |
11 | |
12 #if defined(OS_LINUX) | |
13 #include "media/audio/linux/audio_manager_linux.h" | |
14 #endif // defined(OS_LINUX) | |
15 | |
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 | |
21 | |
22 #if defined(USE_PULSEAUDIO) | |
23 #include "media/audio/pulse/audio_manager_pulse.h" | |
24 #endif // defined(USE_PULSEAUDIO) | |
25 | |
26 namespace media { | |
27 | |
28 // Test fixture which allows us to override the default enumeration API on | |
29 // Windows. | |
30 class AudioInputDeviceTest | |
31 : public ::testing::Test { | |
32 protected: | |
33 AudioInputDeviceTest() | |
34 : audio_manager_(AudioManager::Create()) | |
35 #if defined(OS_WIN) | |
36 , com_init_(base::win::ScopedCOMInitializer::kMTA) | |
37 #endif | |
38 { | |
39 } | |
40 | |
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; | |
48 | |
49 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration); | |
50 return true; | |
51 } | |
52 | |
53 void SetWaveEnumeration() { | |
54 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get()); | |
55 amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration); | |
56 } | |
57 | |
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(); | |
69 } | |
70 #endif | |
71 | |
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(); | |
78 | |
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; | |
84 | |
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; | |
97 } | |
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"; | |
103 } | |
104 } | |
105 | |
106 bool CanRunInputTest() { | |
107 return audio_manager_->HasAudioInputDevices(); | |
108 } | |
109 | |
110 bool CanRunOutputTest() { | |
111 return audio_manager_->HasAudioOutputDevices(); | |
112 } | |
113 | |
114 scoped_ptr<AudioManager> audio_manager_; | |
115 | |
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 | |
120 }; | |
121 | |
122 // Test that devices can be enumerated. | |
123 TEST_F(AudioInputDeviceTest, EnumerateInputDevices) { | |
124 if (!CanRunInputTest()) | |
125 return; | |
126 | |
127 AudioDeviceNames device_names; | |
128 audio_manager_->GetAudioInputDeviceNames(&device_names); | |
129 CheckDeviceNames(device_names); | |
130 } | |
131 | |
132 // Test that devices can be enumerated. | |
133 TEST_F(AudioInputDeviceTest, EnumerateOutputDevices) { | |
134 if (!CanRunOutputTest()) | |
135 return; | |
136 | |
137 AudioDeviceNames device_names; | |
138 audio_manager_->GetAudioOutputDeviceNames(&device_names); | |
139 CheckDeviceNames(device_names); | |
140 } | |
141 | |
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) | |
146 | |
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(AudioInputDeviceTest, EnumerateInputDevicesWinMMDevice) { | |
150 if (!CanRunInputTest()) | |
151 return; | |
152 | |
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; | |
158 } | |
159 audio_manager_->GetAudioInputDeviceNames(&device_names); | |
160 CheckDeviceNames(device_names); | |
161 } | |
162 | |
163 TEST_F(AudioInputDeviceTest, EnumerateOutputDevicesWinMMDevice) { | |
164 if (!CanRunOutputTest()) | |
165 return; | |
166 | |
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; | |
172 } | |
173 audio_manager_->GetAudioOutputDeviceNames(&device_names); | |
174 CheckDeviceNames(device_names); | |
175 } | |
176 | |
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(AudioInputDeviceTest, EnumerateInputDevicesWinWave) { | |
180 if (!CanRunInputTest()) | |
181 return; | |
182 | |
183 AudioDeviceNames device_names; | |
184 SetWaveEnumeration(); | |
185 audio_manager_->GetAudioInputDeviceNames(&device_names); | |
186 CheckDeviceNames(device_names); | |
187 } | |
188 | |
189 TEST_F(AudioInputDeviceTest, EnumerateOutputDevicesWinWave) { | |
190 if (!CanRunOutputTest()) | |
191 return; | |
192 | |
193 AudioDeviceNames device_names; | |
194 SetWaveEnumeration(); | |
195 audio_manager_->GetAudioOutputDeviceNames(&device_names); | |
196 CheckDeviceNames(device_names); | |
197 } | |
198 | |
199 TEST_F(AudioInputDeviceTest, WinXPDeviceIdUnchanged) { | |
200 if (!CanRunInputTest()) | |
201 return; | |
202 | |
203 AudioDeviceNames xp_device_names; | |
204 SetWaveEnumeration(); | |
205 audio_manager_->GetAudioInputDeviceNames(&xp_device_names); | |
206 CheckDeviceNames(xp_device_names); | |
207 | |
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)); | |
213 } | |
214 } | |
215 | |
216 TEST_F(AudioInputDeviceTest, ConvertToWinXPInputDeviceId) { | |
217 if (!CanRunInputTest()) | |
218 return; | |
219 | |
220 if (!SetMMDeviceEnumeration()) { | |
221 // Usage of MMDevice will fail on XP and lower. | |
222 LOG(WARNING) << "MM device enumeration is not supported."; | |
223 return; | |
224 } | |
225 | |
226 AudioDeviceNames device_names; | |
227 audio_manager_->GetAudioInputDeviceNames(&device_names); | |
228 CheckDeviceNames(device_names); | |
229 | |
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); | |
242 } | |
243 } | |
244 } | |
245 | |
246 #endif // defined(OS_WIN) | |
247 | |
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. | |
252 | |
253 TEST_F(AudioInputDeviceTest, EnumerateInputDevicesPulseaudio) { | |
254 if (!CanRunInputTest()) | |
255 return; | |
256 | |
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."; | |
264 } | |
265 } | |
266 | |
267 TEST_F(AudioInputDeviceTest, EnumerateOutputDevicesPulseaudio) { | |
268 if (!CanRunOutputTest()) | |
269 return; | |
270 | |
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."; | |
278 } | |
279 } | |
280 #endif // defined(USE_PULSEAUDIO) | |
281 | |
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. | |
286 | |
287 TEST_F(AudioInputDeviceTest, EnumerateInputDevicesAlsa) { | |
288 if (!CanRunInputTest()) | |
289 return; | |
290 | |
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); | |
296 } | |
297 | |
298 TEST_F(AudioInputDeviceTest, EnumerateOutputDevicesAlsa) { | |
299 if (!CanRunOutputTest()) | |
300 return; | |
301 | |
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); | |
307 } | |
308 #endif // defined(USE_ALSA) | |
309 | |
310 TEST_F(AudioInputDeviceTest, GetDefaultOutputStreamParameters) { | |
311 #if defined(OS_WIN) || defined(OS_MACOSX) | |
312 if (!CanRunInputTest()) | |
313 return; | |
314 | |
315 AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters(); | |
316 EXPECT_TRUE(params.IsValid()); | |
317 #endif // defined(OS_WIN) || defined(OS_MACOSX) | |
318 } | |
319 | |
320 TEST_F(AudioInputDeviceTest, GetAssociatedOutputDeviceID) { | |
321 #if defined(OS_WIN) || defined(OS_MACOSX) | |
322 if (!CanRunInputTest() || !CanRunOutputTest()) | |
323 return; | |
324 | |
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; | |
338 } | |
339 } | |
340 | |
341 EXPECT_TRUE(found_an_associated_device); | |
342 #endif // defined(OS_WIN) || defined(OS_MACOSX) | |
343 } | |
344 | |
345 } // namespace media | |
OLD | NEW |