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.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
13 #include "content/browser/renderer_host/media/audio_input_device_manager_event_handler.h"
14 #include "media/audio/audio_manager_base.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using content::BrowserThread
;
19 using content::BrowserThreadImpl
;
20 using media_stream::AudioInputDeviceManager
;
22 using testing::AnyNumber
;
23 using testing::InSequence
;
24 using testing::Return
;
26 namespace media_stream
{
28 class MockAudioInputDeviceManagerListener
29 : public MediaStreamProviderListener
{
31 MockAudioInputDeviceManagerListener() {}
32 virtual ~MockAudioInputDeviceManagerListener() {}
34 MOCK_METHOD2(Opened
, void(MediaStreamType
, const int));
35 MOCK_METHOD2(Closed
, void(MediaStreamType
, const int));
36 MOCK_METHOD1(DevicesEnumerated
, void(const StreamDeviceInfoArray
&));
37 MOCK_METHOD3(Error
, void(MediaStreamType
, int, MediaStreamProviderError
));
39 virtual void DevicesEnumerated(MediaStreamType service_type
,
40 const StreamDeviceInfoArray
& devices
) {
41 if (service_type
!= content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
)
45 DevicesEnumerated(devices
);
48 StreamDeviceInfoArray devices_
;
51 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener
);
54 class MockAudioInputDeviceManagerEventHandler
55 : public AudioInputDeviceManagerEventHandler
{
57 explicit MockAudioInputDeviceManagerEventHandler(MessageLoop
* message_loop
)
58 : message_loop_(message_loop
) {}
59 virtual ~MockAudioInputDeviceManagerEventHandler() {}
61 MOCK_METHOD2(DeviceStarted
, void(int, const std::string
&));
62 MOCK_METHOD1(DeviceStopped
, void(int));
64 virtual void OnDeviceStarted(int session_id
,
65 const std::string
& device_id
) {
66 message_loop_
->PostTask(
67 FROM_HERE
, base::Bind(
68 &MockAudioInputDeviceManagerEventHandler::DeviceStarted
,
69 base::Unretained(this), session_id
, device_id
));
72 virtual void OnDeviceStopped(int session_id
) {
73 message_loop_
->PostTask(
74 FROM_HERE
, base::Bind(
75 &MockAudioInputDeviceManagerEventHandler::DeviceStopped
,
76 base::Unretained(this), session_id
));
80 MessageLoop
* message_loop_
;
81 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerEventHandler
);
84 ACTION_P(ExitMessageLoop
, message_loop
) {
85 message_loop
->PostTask(FROM_HERE
, MessageLoop::QuitClosure());
88 class AudioInputDeviceManagerTest
: public testing::Test
{
90 AudioInputDeviceManagerTest()
94 audio_input_listener_() {
97 // Returns true iff machine has an audio input device.
98 bool CanRunAudioInputDeviceTests() {
99 return audio_manager_
->HasAudioInputDevices();
103 virtual void SetUp() {
104 // The test must run on Browser::IO.
105 message_loop_
.reset(new MessageLoop(MessageLoop::TYPE_IO
));
106 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
107 message_loop_
.get()));
108 audio_manager_
.reset(media::AudioManager::Create());
110 manager_
= new AudioInputDeviceManager(audio_manager_
.get());
111 audio_input_listener_
.reset(new MockAudioInputDeviceManagerListener());
112 manager_
->Register(audio_input_listener_
.get());
114 // Gets the enumerated device list from the AudioInputDeviceManager.
115 manager_
->EnumerateDevices();
116 EXPECT_CALL(*audio_input_listener_
, DevicesEnumerated(_
))
119 // Waits for the callback.
120 message_loop_
->RunAllPending();
123 virtual void TearDown() {
124 manager_
->Unregister();
128 scoped_ptr
<MessageLoop
> message_loop_
;
129 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
130 scoped_refptr
<AudioInputDeviceManager
> manager_
;
131 scoped_ptr
<MockAudioInputDeviceManagerListener
> audio_input_listener_
;
132 scoped_ptr
<media::AudioManager
> audio_manager_
;
135 DISALLOW_COPY_AND_ASSIGN(AudioInputDeviceManagerTest
);
138 // Opens and closes the devices.
139 TEST_F(AudioInputDeviceManagerTest
, OpenAndCloseDevice
) {
140 if (!CanRunAudioInputDeviceTests())
143 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
147 for (StreamDeviceInfoArray::const_iterator iter
=
148 audio_input_listener_
->devices_
.begin();
149 iter
!= audio_input_listener_
->devices_
.end(); ++iter
) {
150 // Opens/closes the devices.
151 int session_id
= manager_
->Open(*iter
);
152 manager_
->Close(session_id
);
154 // Expected mock call with expected return value.
155 EXPECT_CALL(*audio_input_listener_
,
156 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
159 EXPECT_CALL(*audio_input_listener_
,
160 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
164 // Waits for the callback.
165 message_loop_
->RunAllPending();
169 // Opens multiple devices at one time and closes them later.
170 TEST_F(AudioInputDeviceManagerTest
, OpenMultipleDevices
) {
171 if (!CanRunAudioInputDeviceTests())
174 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
179 const int kDeviceSize
= audio_input_listener_
->devices_
.size();
180 scoped_array
<int> session_id(new int[kDeviceSize
]);
182 // Opens the devices in a loop.
183 for (StreamDeviceInfoArray::const_iterator iter
=
184 audio_input_listener_
->devices_
.begin();
185 iter
!= audio_input_listener_
->devices_
.end(); ++iter
, ++index
) {
186 // Opens the devices.
187 session_id
[index
] = manager_
->Open(*iter
);
189 // Expected mock call with expected returned value.
190 EXPECT_CALL(*audio_input_listener_
,
191 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
195 // Waits for the callback.
196 message_loop_
->RunAllPending();
199 // Checks if the session_ids are unique.
200 for (int i
= 0; i
< kDeviceSize
- 1; ++i
) {
201 for (int k
= i
+1; k
< kDeviceSize
; ++k
) {
202 EXPECT_TRUE(session_id
[i
] != session_id
[k
]);
206 for (int i
= 0; i
< kDeviceSize
; ++i
) {
207 // Closes the devices.
208 manager_
->Close(session_id
[i
]);
209 EXPECT_CALL(*audio_input_listener_
,
210 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
214 // Waits for the callback.
215 message_loop_
->RunAllPending();
219 // Opens a non-existing device.
220 TEST_F(AudioInputDeviceManagerTest
, OpenNotExistingDevice
) {
221 if (!CanRunAudioInputDeviceTests())
225 MediaStreamType stream_type
= content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
;
226 std::string
device_name("device_doesnt_exist");
227 std::string
device_id("id_doesnt_exist");
228 StreamDeviceInfo
dummy_device(stream_type
, device_name
, device_id
, false);
230 int session_id
= manager_
->Open(dummy_device
);
231 EXPECT_CALL(*audio_input_listener_
,
232 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
236 // Waits for the callback.
237 message_loop_
->RunAllPending();
240 // Opens default device twice.
241 TEST_F(AudioInputDeviceManagerTest
, OpenDeviceTwice
) {
242 if (!CanRunAudioInputDeviceTests())
245 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
249 // Opens and closes the default device twice.
250 int first_session_id
= manager_
->Open(
251 audio_input_listener_
->devices_
.front());
252 int second_session_id
= manager_
->Open(
253 audio_input_listener_
->devices_
.front());
254 manager_
->Close(first_session_id
);
255 manager_
->Close(second_session_id
);
257 // Expected mock calls with expected returned values.
258 EXPECT_NE(first_session_id
, second_session_id
);
259 EXPECT_CALL(*audio_input_listener_
,
260 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
263 EXPECT_CALL(*audio_input_listener_
,
264 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
267 EXPECT_CALL(*audio_input_listener_
,
268 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
271 EXPECT_CALL(*audio_input_listener_
,
272 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
276 // Waits for the callback.
277 message_loop_
->RunAllPending();
280 // Starts and closes the sessions after opening the devices.
281 TEST_F(AudioInputDeviceManagerTest
, StartAndStopSession
) {
282 if (!CanRunAudioInputDeviceTests())
285 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
290 const int kDeviceSize
= audio_input_listener_
->devices_
.size();
291 scoped_array
<int> session_id(new int[kDeviceSize
]);
293 // Creates the EventHandler for the sessions.
294 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
295 audio_input_event_handler(
296 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
298 // Loops through the devices and calls Open()/Start()/Stop()/Close() for
300 for (StreamDeviceInfoArray::const_iterator iter
=
301 audio_input_listener_
->devices_
.begin();
302 iter
!= audio_input_listener_
->devices_
.end(); ++iter
, ++index
) {
303 // Note that no DeviceStopped() notification for Event Handler as we have
304 // stopped the device before calling close.
305 session_id
[index
] = manager_
->Open(*iter
);
306 EXPECT_CALL(*audio_input_listener_
,
307 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
310 message_loop_
->RunAllPending();
312 manager_
->Start(session_id
[index
], audio_input_event_handler
.get());
313 EXPECT_CALL(*audio_input_event_handler
,
314 DeviceStarted(session_id
[index
], iter
->device_id
))
316 message_loop_
->RunAllPending();
318 manager_
->Stop(session_id
[index
]);
319 manager_
->Close(session_id
[index
]);
320 EXPECT_CALL(*audio_input_listener_
,
321 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
324 message_loop_
->RunAllPending();
328 // Tests the behavior of calling Close() without calling Stop().
329 TEST_F(AudioInputDeviceManagerTest
, CloseWithoutStopSession
) {
330 if (!CanRunAudioInputDeviceTests())
333 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
338 const int kDeviceSize
= audio_input_listener_
->devices_
.size();
339 scoped_array
<int> session_id(new int[kDeviceSize
]);
341 // Creates the EventHandlers for the sessions.
342 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
343 audio_input_event_handler(
344 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
346 // Loop through the devices, and calls Open()/Start()/Close() for the devices.
347 // Note that we do not call stop.
348 for (StreamDeviceInfoArray::const_iterator iter
=
349 audio_input_listener_
->devices_
.begin();
350 iter
!= audio_input_listener_
->devices_
.end(); ++iter
, ++index
) {
351 // Calls Open()/Start()/Close() for each device.
352 session_id
[index
] = manager_
->Open(*iter
);
353 EXPECT_CALL(*audio_input_listener_
,
354 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
357 message_loop_
->RunAllPending();
359 manager_
->Start(session_id
[index
], audio_input_event_handler
.get());
360 EXPECT_CALL(*audio_input_event_handler
,
361 DeviceStarted(session_id
[index
], iter
->device_id
))
363 message_loop_
->RunAllPending();
365 // Event Handler should get a stop device notification as no stop is called
366 // before closing the device.
367 manager_
->Close(session_id
[index
]);
368 EXPECT_CALL(*audio_input_event_handler
,
369 DeviceStopped(session_id
[index
]))
371 EXPECT_CALL(*audio_input_listener_
,
372 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
375 message_loop_
->RunAllPending();
379 // Starts the same device twice.
380 TEST_F(AudioInputDeviceManagerTest
, StartDeviceTwice
) {
381 if (!CanRunAudioInputDeviceTests())
384 ASSERT_FALSE(audio_input_listener_
->devices_
.empty());
388 // Create one EventHandler for each session.
389 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
391 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
392 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
393 second_event_handler(
394 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
396 // Open the default device twice.
397 StreamDeviceInfoArray::const_iterator iter
=
398 audio_input_listener_
->devices_
.begin();
399 int first_session_id
= manager_
->Open(*iter
);
400 int second_session_id
= manager_
->Open(*iter
);
401 EXPECT_NE(first_session_id
, second_session_id
);
402 EXPECT_CALL(*audio_input_listener_
,
403 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
406 EXPECT_CALL(*audio_input_listener_
,
407 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
410 message_loop_
->RunAllPending();
412 // Calls Start()/Stop()/Close() for the default device twice.
413 manager_
->Start(first_session_id
, first_event_handler
.get());
414 manager_
->Start(second_session_id
, second_event_handler
.get());
415 EXPECT_CALL(*first_event_handler
,
416 DeviceStarted(first_session_id
,
417 media::AudioManagerBase::kDefaultDeviceId
))
419 EXPECT_CALL(*second_event_handler
,
420 DeviceStarted(second_session_id
,
421 media::AudioManagerBase::kDefaultDeviceId
))
423 message_loop_
->RunAllPending();
425 manager_
->Stop(first_session_id
);
426 manager_
->Stop(second_session_id
);
427 manager_
->Close(first_session_id
);
428 manager_
->Close(second_session_id
);
429 EXPECT_CALL(*audio_input_listener_
,
430 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
433 EXPECT_CALL(*audio_input_listener_
,
434 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
437 message_loop_
->RunAllPending();
440 // Starts an invalid session.
441 TEST_F(AudioInputDeviceManagerTest
, StartInvalidSession
) {
442 if (!CanRunAudioInputDeviceTests())
446 // Creates the EventHandlers for the sessions.
447 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
448 audio_input_event_handler(
449 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
451 // Opens the first device.
452 StreamDeviceInfoArray::const_iterator iter
=
453 audio_input_listener_
->devices_
.begin();
454 int session_id
= manager_
->Open(*iter
);
455 EXPECT_CALL(*audio_input_listener_
,
456 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
459 message_loop_
->RunAllPending();
461 // Starts a non-opened device.
462 // This should fail and trigger error code 'kDeviceNotAvailable'.
463 int invalid_session_id
= session_id
+ 1;
464 manager_
->Start(invalid_session_id
, audio_input_event_handler
.get());
465 EXPECT_CALL(*audio_input_event_handler
,
466 DeviceStarted(invalid_session_id
,
467 AudioInputDeviceManager::kInvalidDeviceId
))
469 message_loop_
->RunAllPending();
471 manager_
->Close(session_id
);
472 EXPECT_CALL(*audio_input_listener_
,
473 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
476 message_loop_
->RunAllPending();
479 // Starts a session twice, the first time should succeed, while the second
481 TEST_F(AudioInputDeviceManagerTest
, StartSessionTwice
) {
482 if (!CanRunAudioInputDeviceTests())
486 // Creates the EventHandlers for the sessions.
487 scoped_ptr
<MockAudioInputDeviceManagerEventHandler
>
488 audio_input_event_handler(
489 new MockAudioInputDeviceManagerEventHandler(message_loop_
.get()));
491 // Opens the first device.
492 StreamDeviceInfoArray::const_iterator iter
=
493 audio_input_listener_
->devices_
.begin();
494 int session_id
= manager_
->Open(*iter
);
495 EXPECT_CALL(*audio_input_listener_
,
496 Opened(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
499 message_loop_
->RunAllPending();
501 // Starts the session, it should succeed.
502 manager_
->Start(session_id
, audio_input_event_handler
.get());
503 EXPECT_CALL(*audio_input_event_handler
,
504 DeviceStarted(session_id
,
505 media::AudioManagerBase::kDefaultDeviceId
))
507 message_loop_
->RunAllPending();
509 // Starts the session for the second time, it should fail.
510 manager_
->Start(session_id
, audio_input_event_handler
.get());
511 EXPECT_CALL(*audio_input_event_handler
,
512 DeviceStarted(session_id
,
513 AudioInputDeviceManager::kInvalidDeviceId
))
516 manager_
->Stop(session_id
);
517 manager_
->Close(session_id
);
518 EXPECT_CALL(*audio_input_listener_
,
519 Closed(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE
,
522 message_loop_
->RunAllPending();
525 } // namespace media_stream