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.
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"
13 #include "base/win/scoped_com_initializer.h"
14 #include "media/audio/win/audio_manager_win.h"
15 #include "media/audio/win/wavein_input_win.h"
20 // Test fixture which allows us to override the default enumeration API on
22 class AudioInputDeviceTest
23 : public ::testing::Test
{
25 AudioInputDeviceTest()
26 : audio_manager_(AudioManager::Create())
28 , com_init_(base::win::ScopedCOMInitializer::kMTA
)
34 bool SetMMDeviceEnumeration() {
35 AudioManagerWin
* amw
= static_cast<AudioManagerWin
*>(audio_manager_
.get());
36 // Windows Wave is used as default if Windows XP was detected =>
37 // return false since MMDevice is not supported on XP.
38 if (amw
->enumeration_type() == AudioManagerWin::kWaveEnumeration
)
41 amw
->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration
);
45 void SetWaveEnumeration() {
46 AudioManagerWin
* amw
= static_cast<AudioManagerWin
*>(audio_manager_
.get());
47 amw
->SetEnumerationType(AudioManagerWin::kWaveEnumeration
);
50 std::string
GetDeviceIdFromPCMWaveInAudioInputStream(
51 const std::string
& device_id
) {
52 AudioManagerWin
* amw
= static_cast<AudioManagerWin
*>(audio_manager_
.get());
53 AudioParameters
parameters(
54 AudioParameters::AUDIO_PCM_LINEAR
, CHANNEL_LAYOUT_STEREO
,
55 AudioParameters::kAudioCDSampleRate
, 16,
57 scoped_ptr
<PCMWaveInAudioInputStream
> stream(
58 static_cast<PCMWaveInAudioInputStream
*>(
59 amw
->CreatePCMWaveInAudioInputStream(parameters
, device_id
)));
60 return stream
.get() ? stream
->device_id_
: std::string();
64 // Helper method which verifies that the device list starts with a valid
65 // default record followed by non-default device names.
66 static void CheckDeviceNames(const AudioDeviceNames
& device_names
) {
67 if (!device_names
.empty()) {
68 AudioDeviceNames::const_iterator it
= device_names
.begin();
70 // The first device in the list should always be the default device.
71 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName
),
73 EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId
), it
->unique_id
);
76 // Other devices should have non-empty name and id and should not contain
77 // default name or id.
78 while (it
!= device_names
.end()) {
79 EXPECT_FALSE(it
->device_name
.empty());
80 EXPECT_FALSE(it
->unique_id
.empty());
81 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName
),
83 EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId
),
88 // Log a warning so we can see the status on the build bots. No need to
89 // break the test though since this does successfully test the code and
90 // some failure cases.
91 LOG(WARNING
) << "No input devices detected";
95 bool CanRunAudioTest() {
96 return audio_manager_
->HasAudioInputDevices();
99 scoped_ptr
<AudioManager
> audio_manager_
;
102 // The MMDevice API requires COM to be initialized on the current thread.
103 base::win::ScopedCOMInitializer com_init_
;
107 // Test that devices can be enumerated.
108 TEST_F(AudioInputDeviceTest
, EnumerateDevices
) {
109 if (!CanRunAudioTest())
112 AudioDeviceNames device_names
;
113 audio_manager_
->GetAudioInputDeviceNames(&device_names
);
114 CheckDeviceNames(device_names
);
117 // Run additional tests for Windows since enumeration can be done using
118 // two different APIs. MMDevice is default for Vista and higher and Wave
119 // is default for XP and lower.
122 // Override default enumeration API and force usage of Windows MMDevice.
123 // This test will only run on Windows Vista and higher.
124 TEST_F(AudioInputDeviceTest
, EnumerateDevicesWinMMDevice
) {
125 if (!CanRunAudioTest())
128 AudioDeviceNames device_names
;
129 if (!SetMMDeviceEnumeration()) {
130 // Usage of MMDevice will fail on XP and lower.
131 LOG(WARNING
) << "MM device enumeration is not supported.";
134 audio_manager_
->GetAudioInputDeviceNames(&device_names
);
135 CheckDeviceNames(device_names
);
138 // Override default enumeration API and force usage of Windows Wave.
139 // This test will run on Windows XP, Windows Vista and Windows 7.
140 TEST_F(AudioInputDeviceTest
, EnumerateDevicesWinWave
) {
141 if (!CanRunAudioTest())
144 AudioDeviceNames device_names
;
145 SetWaveEnumeration();
146 audio_manager_
->GetAudioInputDeviceNames(&device_names
);
147 CheckDeviceNames(device_names
);
150 TEST_F(AudioInputDeviceTest
, WinXPDeviceIdUnchanged
) {
151 if (!CanRunAudioTest())
154 AudioDeviceNames xp_device_names
;
155 SetWaveEnumeration();
156 audio_manager_
->GetAudioInputDeviceNames(&xp_device_names
);
157 CheckDeviceNames(xp_device_names
);
159 // Device ID should remain unchanged, including the default device ID.
160 for (AudioDeviceNames::iterator i
= xp_device_names
.begin();
161 i
!= xp_device_names
.end(); ++i
) {
162 EXPECT_EQ(i
->unique_id
,
163 GetDeviceIdFromPCMWaveInAudioInputStream(i
->unique_id
));
167 TEST_F(AudioInputDeviceTest
, ConvertToWinXPDeviceId
) {
168 if (!CanRunAudioTest())
171 if (!SetMMDeviceEnumeration()) {
172 // Usage of MMDevice will fail on XP and lower.
173 LOG(WARNING
) << "MM device enumeration is not supported.";
177 AudioDeviceNames device_names
;
178 audio_manager_
->GetAudioInputDeviceNames(&device_names
);
179 CheckDeviceNames(device_names
);
181 for (AudioDeviceNames::iterator i
= device_names
.begin();
182 i
!= device_names
.end(); ++i
) {
183 std::string converted_id
=
184 GetDeviceIdFromPCMWaveInAudioInputStream(i
->unique_id
);
185 if (i
== device_names
.begin()) {
186 // The first in the list is the default device ID, which should not be
187 // changed when passed to PCMWaveInAudioInputStream.
188 EXPECT_EQ(i
->unique_id
, converted_id
);
190 // MMDevice-style device IDs should be converted to WaveIn-style device
192 EXPECT_NE(i
->unique_id
, converted_id
);