Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / media / audio / audio_manager_unittest.cc
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.
4
5 #include "base/environment.h"
6 #include "base/logging.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "media/audio/audio_manager.h"
10 #include "media/audio/audio_manager_base.h"
11 #include "media/audio/fake_audio_log_factory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 #if defined(USE_ALSA)
15 #include "media/audio/alsa/audio_manager_alsa.h"
16 #endif  // defined(USE_ALSA)
17
18 #if defined(OS_WIN)
19 #include "base/win/scoped_com_initializer.h"
20 #include "media/audio/win/audio_manager_win.h"
21 #include "media/audio/win/wavein_input_win.h"
22 #endif
23
24 #if defined(USE_PULSEAUDIO)
25 #include "media/audio/pulse/audio_manager_pulse.h"
26 #endif  // defined(USE_PULSEAUDIO)
27
28 namespace media {
29
30 // Test fixture which allows us to override the default enumeration API on
31 // Windows.
32 class AudioManagerTest
33     : public ::testing::Test {
34  protected:
35   AudioManagerTest()
36       : audio_manager_(AudioManager::CreateForTesting())
37 #if defined(OS_WIN)
38       , com_init_(base::win::ScopedCOMInitializer::kMTA)
39 #endif
40   {
41     // Wait for audio thread initialization to complete.  Otherwise the
42     // enumeration type may not have been set yet.
43     base::WaitableEvent event(false, false);
44     audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
45         &base::WaitableEvent::Signal, base::Unretained(&event)));
46     event.Wait();
47   }
48
49 #if defined(OS_WIN)
50   bool SetMMDeviceEnumeration() {
51     AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
52     // Windows Wave is used as default if Windows XP was detected =>
53     // return false since MMDevice is not supported on XP.
54     if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
55       return false;
56
57     amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
58     return true;
59   }
60
61   void SetWaveEnumeration() {
62     AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
63     amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
64   }
65
66   std::string GetDeviceIdFromPCMWaveInAudioInputStream(
67       const std::string& device_id) {
68     AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
69     AudioParameters parameters(
70         AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
71         AudioParameters::kAudioCDSampleRate, 16,
72         1024);
73     scoped_ptr<PCMWaveInAudioInputStream> stream(
74         static_cast<PCMWaveInAudioInputStream*>(
75             amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
76     return stream.get() ? stream->device_id_ : std::string();
77   }
78 #endif
79
80   // Helper method which verifies that the device list starts with a valid
81   // default record followed by non-default device names.
82   static void CheckDeviceNames(const AudioDeviceNames& device_names) {
83     VLOG(2) << "Got " << device_names.size() << " audio devices.";
84     if (!device_names.empty()) {
85       AudioDeviceNames::const_iterator it = device_names.begin();
86
87       // The first device in the list should always be the default device.
88       EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
89                 it->device_name);
90       EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
91       ++it;
92
93       // Other devices should have non-empty name and id and should not contain
94       // default name or id.
95       while (it != device_names.end()) {
96         EXPECT_FALSE(it->device_name.empty());
97         EXPECT_FALSE(it->unique_id.empty());
98         VLOG(2) << "Device ID(" << it->unique_id
99                 << "), label: " << it->device_name;
100         EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceName),
101                   it->device_name);
102         EXPECT_NE(std::string(AudioManagerBase::kDefaultDeviceId),
103                   it->unique_id);
104         ++it;
105       }
106     } else {
107       // Log a warning so we can see the status on the build bots.  No need to
108       // break the test though since this does successfully test the code and
109       // some failure cases.
110       LOG(WARNING) << "No input devices detected";
111     }
112   }
113
114   bool CanRunInputTest() {
115     return audio_manager_->HasAudioInputDevices();
116   }
117
118   bool CanRunOutputTest() {
119     return audio_manager_->HasAudioOutputDevices();
120   }
121
122 #if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
123   template <class T>
124   void CreateAudioManagerForTesting() {
125     // Only one AudioManager may exist at a time, so destroy the one we're
126     // currently holding before creating a new one.
127     audio_manager_.reset();
128     audio_manager_.reset(T::Create(&fake_audio_log_factory_));
129   }
130 #endif
131
132   FakeAudioLogFactory fake_audio_log_factory_;
133   scoped_ptr<AudioManager> audio_manager_;
134
135 #if defined(OS_WIN)
136   // The MMDevice API requires COM to be initialized on the current thread.
137   base::win::ScopedCOMInitializer com_init_;
138 #endif
139 };
140
141 // Test that devices can be enumerated.
142 TEST_F(AudioManagerTest, EnumerateInputDevices) {
143   if (!CanRunInputTest())
144     return;
145
146   AudioDeviceNames device_names;
147   audio_manager_->GetAudioInputDeviceNames(&device_names);
148   CheckDeviceNames(device_names);
149 }
150
151 // Test that devices can be enumerated.
152 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
153   if (!CanRunOutputTest())
154     return;
155
156   AudioDeviceNames device_names;
157   audio_manager_->GetAudioOutputDeviceNames(&device_names);
158   CheckDeviceNames(device_names);
159 }
160
161 // Run additional tests for Windows since enumeration can be done using
162 // two different APIs. MMDevice is default for Vista and higher and Wave
163 // is default for XP and lower.
164 #if defined(OS_WIN)
165
166 // Override default enumeration API and force usage of Windows MMDevice.
167 // This test will only run on Windows Vista and higher.
168 TEST_F(AudioManagerTest, EnumerateInputDevicesWinMMDevice) {
169   if (!CanRunInputTest())
170     return;
171
172   AudioDeviceNames device_names;
173   if (!SetMMDeviceEnumeration()) {
174     // Usage of MMDevice will fail on XP and lower.
175     LOG(WARNING) << "MM device enumeration is not supported.";
176     return;
177   }
178   audio_manager_->GetAudioInputDeviceNames(&device_names);
179   CheckDeviceNames(device_names);
180 }
181
182 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinMMDevice) {
183   if (!CanRunOutputTest())
184     return;
185
186   AudioDeviceNames device_names;
187   if (!SetMMDeviceEnumeration()) {
188     // Usage of MMDevice will fail on XP and lower.
189     LOG(WARNING) << "MM device enumeration is not supported.";
190     return;
191   }
192   audio_manager_->GetAudioOutputDeviceNames(&device_names);
193   CheckDeviceNames(device_names);
194 }
195
196 // Override default enumeration API and force usage of Windows Wave.
197 // This test will run on Windows XP, Windows Vista and Windows 7.
198 TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
199   if (!CanRunInputTest())
200     return;
201
202   AudioDeviceNames device_names;
203   SetWaveEnumeration();
204   audio_manager_->GetAudioInputDeviceNames(&device_names);
205   CheckDeviceNames(device_names);
206 }
207
208 TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
209   if (!CanRunOutputTest())
210     return;
211
212   AudioDeviceNames device_names;
213   SetWaveEnumeration();
214   audio_manager_->GetAudioOutputDeviceNames(&device_names);
215   CheckDeviceNames(device_names);
216 }
217
218 TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
219   if (!CanRunInputTest())
220     return;
221
222   AudioDeviceNames xp_device_names;
223   SetWaveEnumeration();
224   audio_manager_->GetAudioInputDeviceNames(&xp_device_names);
225   CheckDeviceNames(xp_device_names);
226
227   // Device ID should remain unchanged, including the default device ID.
228   for (AudioDeviceNames::iterator i = xp_device_names.begin();
229        i != xp_device_names.end(); ++i) {
230     EXPECT_EQ(i->unique_id,
231               GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id));
232   }
233 }
234
235 TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
236   if (!CanRunInputTest())
237     return;
238
239   if (!SetMMDeviceEnumeration()) {
240     // Usage of MMDevice will fail on XP and lower.
241     LOG(WARNING) << "MM device enumeration is not supported.";
242     return;
243   }
244
245   AudioDeviceNames device_names;
246   audio_manager_->GetAudioInputDeviceNames(&device_names);
247   CheckDeviceNames(device_names);
248
249   for (AudioDeviceNames::iterator i = device_names.begin();
250        i != device_names.end(); ++i) {
251     std::string converted_id =
252         GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
253     if (i == device_names.begin()) {
254       // The first in the list is the default device ID, which should not be
255       // changed when passed to PCMWaveInAudioInputStream.
256       EXPECT_EQ(i->unique_id, converted_id);
257     } else {
258       // MMDevice-style device IDs should be converted to WaveIn-style device
259       // IDs.
260       EXPECT_NE(i->unique_id, converted_id);
261     }
262   }
263 }
264
265 #endif  // defined(OS_WIN)
266
267 #if defined(USE_PULSEAUDIO)
268 // On Linux, there are two implementations available and both can
269 // sometimes be tested on a single system. These tests specifically
270 // test Pulseaudio.
271
272 TEST_F(AudioManagerTest, EnumerateInputDevicesPulseaudio) {
273   if (!CanRunInputTest())
274     return;
275
276   CreateAudioManagerForTesting<AudioManagerPulse>();
277   if (audio_manager_.get()) {
278     AudioDeviceNames device_names;
279     audio_manager_->GetAudioInputDeviceNames(&device_names);
280     CheckDeviceNames(device_names);
281   } else {
282     LOG(WARNING) << "No pulseaudio on this system.";
283   }
284 }
285
286 TEST_F(AudioManagerTest, EnumerateOutputDevicesPulseaudio) {
287   if (!CanRunOutputTest())
288     return;
289
290   CreateAudioManagerForTesting<AudioManagerPulse>();
291   if (audio_manager_.get()) {
292     AudioDeviceNames device_names;
293     audio_manager_->GetAudioOutputDeviceNames(&device_names);
294     CheckDeviceNames(device_names);
295   } else {
296     LOG(WARNING) << "No pulseaudio on this system.";
297   }
298 }
299 #endif  // defined(USE_PULSEAUDIO)
300
301 #if defined(USE_ALSA)
302 // On Linux, there are two implementations available and both can
303 // sometimes be tested on a single system. These tests specifically
304 // test Alsa.
305
306 TEST_F(AudioManagerTest, EnumerateInputDevicesAlsa) {
307   if (!CanRunInputTest())
308     return;
309
310   VLOG(2) << "Testing AudioManagerAlsa.";
311   CreateAudioManagerForTesting<AudioManagerAlsa>();
312   AudioDeviceNames device_names;
313   audio_manager_->GetAudioInputDeviceNames(&device_names);
314   CheckDeviceNames(device_names);
315 }
316
317 TEST_F(AudioManagerTest, EnumerateOutputDevicesAlsa) {
318   if (!CanRunOutputTest())
319     return;
320
321   VLOG(2) << "Testing AudioManagerAlsa.";
322   CreateAudioManagerForTesting<AudioManagerAlsa>();
323   AudioDeviceNames device_names;
324   audio_manager_->GetAudioOutputDeviceNames(&device_names);
325   CheckDeviceNames(device_names);
326 }
327 #endif  // defined(USE_ALSA)
328
329 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
330 #if defined(OS_WIN) || defined(OS_MACOSX)
331   if (!CanRunInputTest())
332     return;
333
334   AudioParameters params = audio_manager_->GetDefaultOutputStreamParameters();
335   EXPECT_TRUE(params.IsValid());
336 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
337 }
338
339 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
340 #if defined(OS_WIN) || defined(OS_MACOSX)
341   if (!CanRunInputTest() || !CanRunOutputTest())
342     return;
343
344   AudioDeviceNames device_names;
345   audio_manager_->GetAudioInputDeviceNames(&device_names);
346   bool found_an_associated_device = false;
347   for (AudioDeviceNames::iterator it = device_names.begin();
348        it != device_names.end();
349        ++it) {
350     EXPECT_FALSE(it->unique_id.empty());
351     EXPECT_FALSE(it->device_name.empty());
352     std::string output_device_id(
353         audio_manager_->GetAssociatedOutputDeviceID(it->unique_id));
354     if (!output_device_id.empty()) {
355       VLOG(2) << it->unique_id << " matches with " << output_device_id;
356       found_an_associated_device = true;
357     }
358   }
359
360   EXPECT_TRUE(found_an_associated_device);
361 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
362 }
363
364 }  // namespace media