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.
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
14 #include "content/public/common/media_stream_request.h"
15 #include "media/audio/audio_manager_base.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::InSequence
;
21 using testing::SaveArg
;
22 using testing::Return
;
26 class MockAudioInputDeviceManagerListener
27 : public MediaStreamProviderListener
{
29 MockAudioInputDeviceManagerListener() {}
30 virtual ~MockAudioInputDeviceManagerListener() {}
32 MOCK_METHOD2(Opened
, void(MediaStreamType
, const int));
33 MOCK_METHOD2(Closed
, void(MediaStreamType
, const int));
34 MOCK_METHOD2(DevicesEnumerated
, void(MediaStreamType
,
35 const StreamDeviceInfoArray
&));
36 MOCK_METHOD2(Aborted
, void(MediaStreamType
, int));
38 StreamDeviceInfoArray devices_
;
41 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener
);
44 // TODO(henrika): there are special restrictions for Android since
45 // AudioInputDeviceManager::Open() must be called on the audio thread.
46 // This test suite must be modified to run on Android.
47 #if defined(OS_ANDROID)
48 #define MAYBE_AudioInputDeviceManagerTest DISABLED_AudioInputDeviceManagerTest
50 #define MAYBE_AudioInputDeviceManagerTest AudioInputDeviceManagerTest
53 class MAYBE_AudioInputDeviceManagerTest
: public testing::Test
{
55 MAYBE_AudioInputDeviceManagerTest() {}
57 // Returns true iff machine has an audio input device.
58 bool CanRunAudioInputDeviceTests() {
59 return audio_manager_
->HasAudioInputDevices();
63 virtual void SetUp() OVERRIDE
{
64 // The test must run on Browser::IO.
65 message_loop_
.reset(new base::MessageLoopForIO
);
66 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
67 message_loop_
.get()));
68 audio_manager_
.reset(media::AudioManager::CreateForTesting());
69 // Wait for audio thread initialization to complete. Otherwise the
70 // enumeration type may not have been set yet.
71 base::WaitableEvent
event(false, false);
72 audio_manager_
->GetTaskRunner()->PostTask(FROM_HERE
, base::Bind(
73 &base::WaitableEvent::Signal
, base::Unretained(&event
)));
75 manager_
= new AudioInputDeviceManager(audio_manager_
.get());
76 audio_input_listener_
.reset(new MockAudioInputDeviceManagerListener());
77 manager_
->Register(audio_input_listener_
.get(),
78 message_loop_
->message_loop_proxy().get());
80 // Gets the enumerated device list from the AudioInputDeviceManager.
81 manager_
->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE
);
82 EXPECT_CALL(*audio_input_listener_
,
83 DevicesEnumerated(MEDIA_DEVICE_AUDIO_CAPTURE
, _
))
85 .WillOnce(SaveArg
<1>(&devices_
));
87 // Wait until we get the list.
88 message_loop_
->RunUntilIdle();
91 virtual void TearDown() OVERRIDE
{
92 manager_
->Unregister();
96 scoped_ptr
<base::MessageLoop
> message_loop_
;
97 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
98 scoped_refptr
<AudioInputDeviceManager
> manager_
;
99 scoped_ptr
<MockAudioInputDeviceManagerListener
> audio_input_listener_
;
100 scoped_ptr
<media::AudioManager
> audio_manager_
;
101 StreamDeviceInfoArray devices_
;
104 DISALLOW_COPY_AND_ASSIGN(MAYBE_AudioInputDeviceManagerTest
);
107 // Opens and closes the devices.
108 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenAndCloseDevice
) {
109 if (!CanRunAudioInputDeviceTests())
112 ASSERT_FALSE(devices_
.empty());
116 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
117 iter
!= devices_
.end(); ++iter
) {
118 // Opens/closes the devices.
119 int session_id
= manager_
->Open(*iter
);
121 // Expected mock call with expected return value.
122 EXPECT_CALL(*audio_input_listener_
,
123 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
125 // Waits for the callback.
126 message_loop_
->RunUntilIdle();
128 manager_
->Close(session_id
);
129 EXPECT_CALL(*audio_input_listener_
,
130 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
133 // Waits for the callback.
134 message_loop_
->RunUntilIdle();
138 // Opens multiple devices at one time and closes them later.
139 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenMultipleDevices
) {
140 if (!CanRunAudioInputDeviceTests())
143 ASSERT_FALSE(devices_
.empty());
148 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
150 // Opens the devices in a loop.
151 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
152 iter
!= devices_
.end(); ++iter
, ++index
) {
153 // Opens the devices.
154 session_id
[index
] = manager_
->Open(*iter
);
156 // Expected mock call with expected returned value.
157 EXPECT_CALL(*audio_input_listener_
,
158 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
161 // Waits for the callback.
162 message_loop_
->RunUntilIdle();
165 // Checks if the session_ids are unique.
166 for (size_t i
= 0; i
< devices_
.size() - 1; ++i
) {
167 for (size_t k
= i
+ 1; k
< devices_
.size(); ++k
) {
168 EXPECT_TRUE(session_id
[i
] != session_id
[k
]);
172 for (size_t i
= 0; i
< devices_
.size(); ++i
) {
173 // Closes the devices.
174 manager_
->Close(session_id
[i
]);
175 EXPECT_CALL(*audio_input_listener_
,
176 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[i
]))
179 // Waits for the callback.
180 message_loop_
->RunUntilIdle();
184 // Opens a non-existing device.
185 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenNotExistingDevice
) {
186 if (!CanRunAudioInputDeviceTests())
190 MediaStreamType stream_type
= MEDIA_DEVICE_AUDIO_CAPTURE
;
191 std::string
device_name("device_doesnt_exist");
192 std::string
device_id("id_doesnt_exist");
194 int channel_config(0);
195 StreamDeviceInfo
dummy_device(
196 stream_type
, device_name
, device_id
, sample_rate
, channel_config
, 2048);
198 int session_id
= manager_
->Open(dummy_device
);
199 EXPECT_CALL(*audio_input_listener_
,
200 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
203 // Waits for the callback.
204 message_loop_
->RunUntilIdle();
207 // Opens default device twice.
208 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenDeviceTwice
) {
209 if (!CanRunAudioInputDeviceTests())
212 ASSERT_FALSE(devices_
.empty());
216 // Opens and closes the default device twice.
217 int first_session_id
= manager_
->Open(devices_
.front());
218 int second_session_id
= manager_
->Open(devices_
.front());
220 // Expected mock calls with expected returned values.
221 EXPECT_NE(first_session_id
, second_session_id
);
222 EXPECT_CALL(*audio_input_listener_
,
223 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
225 EXPECT_CALL(*audio_input_listener_
,
226 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
228 // Waits for the callback.
229 message_loop_
->RunUntilIdle();
231 manager_
->Close(first_session_id
);
232 manager_
->Close(second_session_id
);
233 EXPECT_CALL(*audio_input_listener_
,
234 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
236 EXPECT_CALL(*audio_input_listener_
,
237 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
239 // Waits for the callback.
240 message_loop_
->RunUntilIdle();
243 // Accesses then closes the sessions after opening the devices.
244 TEST_F(MAYBE_AudioInputDeviceManagerTest
, AccessAndCloseSession
) {
245 if (!CanRunAudioInputDeviceTests())
248 ASSERT_FALSE(devices_
.empty());
253 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
255 // Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
257 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
258 iter
!= devices_
.end(); ++iter
, ++index
) {
259 // Note that no DeviceStopped() notification for Event Handler as we have
260 // stopped the device before calling close.
261 session_id
[index
] = manager_
->Open(*iter
);
262 EXPECT_CALL(*audio_input_listener_
,
263 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
265 message_loop_
->RunUntilIdle();
267 const StreamDeviceInfo
* info
= manager_
->GetOpenedDeviceInfoById(
270 EXPECT_EQ(iter
->device
.id
, info
->device
.id
);
271 manager_
->Close(session_id
[index
]);
272 EXPECT_CALL(*audio_input_listener_
,
273 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
275 message_loop_
->RunUntilIdle();
279 // Access an invalid session.
280 TEST_F(MAYBE_AudioInputDeviceManagerTest
, AccessInvalidSession
) {
281 if (!CanRunAudioInputDeviceTests())
285 // Opens the first device.
286 StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
287 int session_id
= manager_
->Open(*iter
);
288 EXPECT_CALL(*audio_input_listener_
,
289 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
291 message_loop_
->RunUntilIdle();
293 // Access a non-opened device.
294 // This should fail and return an empty StreamDeviceInfo.
295 int invalid_session_id
= session_id
+ 1;
296 const StreamDeviceInfo
* info
=
297 manager_
->GetOpenedDeviceInfoById(invalid_session_id
);
300 manager_
->Close(session_id
);
301 EXPECT_CALL(*audio_input_listener_
,
302 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
304 message_loop_
->RunUntilIdle();
307 } // namespace content