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/public/common/media_stream_request.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"
19 using testing::InSequence
;
20 using testing::SaveArg
;
21 using testing::Return
;
25 class MockAudioInputDeviceManagerListener
26 : public MediaStreamProviderListener
{
28 MockAudioInputDeviceManagerListener() {}
29 virtual ~MockAudioInputDeviceManagerListener() {}
31 MOCK_METHOD2(Opened
, void(MediaStreamType
, const int));
32 MOCK_METHOD2(Closed
, void(MediaStreamType
, const int));
33 MOCK_METHOD2(DevicesEnumerated
, void(MediaStreamType
,
34 const StreamDeviceInfoArray
&));
35 MOCK_METHOD3(Error
, void(MediaStreamType
, int, MediaStreamProviderError
));
37 StreamDeviceInfoArray devices_
;
40 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener
);
43 class AudioInputDeviceManagerTest
: public testing::Test
{
45 AudioInputDeviceManagerTest() {}
47 // Returns true iff machine has an audio input device.
48 bool CanRunAudioInputDeviceTests() {
49 return audio_manager_
->HasAudioInputDevices();
53 virtual void SetUp() OVERRIDE
{
54 // The test must run on Browser::IO.
55 message_loop_
.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO
));
56 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
57 message_loop_
.get()));
58 audio_manager_
.reset(media::AudioManager::Create());
59 manager_
= new AudioInputDeviceManager(audio_manager_
.get());
60 audio_input_listener_
.reset(new MockAudioInputDeviceManagerListener());
61 manager_
->Register(audio_input_listener_
.get(),
62 message_loop_
->message_loop_proxy().get());
64 // Gets the enumerated device list from the AudioInputDeviceManager.
65 manager_
->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE
);
66 EXPECT_CALL(*audio_input_listener_
,
67 DevicesEnumerated(MEDIA_DEVICE_AUDIO_CAPTURE
, _
))
69 .WillOnce(SaveArg
<1>(&devices_
));
71 // Wait until we get the list.
72 message_loop_
->RunUntilIdle();
75 virtual void TearDown() OVERRIDE
{
76 manager_
->Unregister();
80 scoped_ptr
<base::MessageLoop
> message_loop_
;
81 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
82 scoped_refptr
<AudioInputDeviceManager
> manager_
;
83 scoped_ptr
<MockAudioInputDeviceManagerListener
> audio_input_listener_
;
84 scoped_ptr
<media::AudioManager
> audio_manager_
;
85 StreamDeviceInfoArray devices_
;
88 DISALLOW_COPY_AND_ASSIGN(AudioInputDeviceManagerTest
);
91 // Opens and closes the devices.
92 TEST_F(AudioInputDeviceManagerTest
, OpenAndCloseDevice
) {
93 if (!CanRunAudioInputDeviceTests())
96 ASSERT_FALSE(devices_
.empty());
100 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
101 iter
!= devices_
.end(); ++iter
) {
102 // Opens/closes the devices.
103 int session_id
= manager_
->Open(*iter
);
105 // Expected mock call with expected return value.
106 EXPECT_CALL(*audio_input_listener_
,
107 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
109 // Waits for the callback.
110 message_loop_
->RunUntilIdle();
112 manager_
->Close(session_id
);
113 EXPECT_CALL(*audio_input_listener_
,
114 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
117 // Waits for the callback.
118 message_loop_
->RunUntilIdle();
122 // Opens multiple devices at one time and closes them later.
123 TEST_F(AudioInputDeviceManagerTest
, OpenMultipleDevices
) {
124 if (!CanRunAudioInputDeviceTests())
127 ASSERT_FALSE(devices_
.empty());
132 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
134 // Opens the devices in a loop.
135 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
136 iter
!= devices_
.end(); ++iter
, ++index
) {
137 // Opens the devices.
138 session_id
[index
] = manager_
->Open(*iter
);
140 // Expected mock call with expected returned value.
141 EXPECT_CALL(*audio_input_listener_
,
142 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
145 // Waits for the callback.
146 message_loop_
->RunUntilIdle();
149 // Checks if the session_ids are unique.
150 for (size_t i
= 0; i
< devices_
.size() - 1; ++i
) {
151 for (size_t k
= i
+ 1; k
< devices_
.size(); ++k
) {
152 EXPECT_TRUE(session_id
[i
] != session_id
[k
]);
156 for (size_t i
= 0; i
< devices_
.size(); ++i
) {
157 // Closes the devices.
158 manager_
->Close(session_id
[i
]);
159 EXPECT_CALL(*audio_input_listener_
,
160 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[i
]))
163 // Waits for the callback.
164 message_loop_
->RunUntilIdle();
168 // Opens a non-existing device.
169 TEST_F(AudioInputDeviceManagerTest
, OpenNotExistingDevice
) {
170 if (!CanRunAudioInputDeviceTests())
174 MediaStreamType stream_type
= MEDIA_DEVICE_AUDIO_CAPTURE
;
175 std::string
device_name("device_doesnt_exist");
176 std::string
device_id("id_doesnt_exist");
178 int channel_config(0);
179 StreamDeviceInfo
dummy_device(
180 stream_type
, device_name
, device_id
, sample_rate
, channel_config
, false);
182 int session_id
= manager_
->Open(dummy_device
);
183 EXPECT_CALL(*audio_input_listener_
,
184 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
187 // Waits for the callback.
188 message_loop_
->RunUntilIdle();
191 // Opens default device twice.
192 TEST_F(AudioInputDeviceManagerTest
, OpenDeviceTwice
) {
193 if (!CanRunAudioInputDeviceTests())
196 ASSERT_FALSE(devices_
.empty());
200 // Opens and closes the default device twice.
201 int first_session_id
= manager_
->Open(devices_
.front());
202 int second_session_id
= manager_
->Open(devices_
.front());
204 // Expected mock calls with expected returned values.
205 EXPECT_NE(first_session_id
, second_session_id
);
206 EXPECT_CALL(*audio_input_listener_
,
207 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
209 EXPECT_CALL(*audio_input_listener_
,
210 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
212 // Waits for the callback.
213 message_loop_
->RunUntilIdle();
215 manager_
->Close(first_session_id
);
216 manager_
->Close(second_session_id
);
217 EXPECT_CALL(*audio_input_listener_
,
218 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
220 EXPECT_CALL(*audio_input_listener_
,
221 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
223 // Waits for the callback.
224 message_loop_
->RunUntilIdle();
227 // Accesses then closes the sessions after opening the devices.
228 TEST_F(AudioInputDeviceManagerTest
, AccessAndCloseSession
) {
229 if (!CanRunAudioInputDeviceTests())
232 ASSERT_FALSE(devices_
.empty());
237 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
239 // Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
241 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
242 iter
!= devices_
.end(); ++iter
, ++index
) {
243 // Note that no DeviceStopped() notification for Event Handler as we have
244 // stopped the device before calling close.
245 session_id
[index
] = manager_
->Open(*iter
);
246 EXPECT_CALL(*audio_input_listener_
,
247 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
249 message_loop_
->RunUntilIdle();
251 const StreamDeviceInfo
* info
= manager_
->GetOpenedDeviceInfoById(
254 EXPECT_EQ(iter
->device
.id
, info
->device
.id
);
255 manager_
->Close(session_id
[index
]);
256 EXPECT_CALL(*audio_input_listener_
,
257 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
259 message_loop_
->RunUntilIdle();
263 // Access an invalid session.
264 TEST_F(AudioInputDeviceManagerTest
, AccessInvalidSession
) {
265 if (!CanRunAudioInputDeviceTests())
269 // Opens the first device.
270 StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
271 int session_id
= manager_
->Open(*iter
);
272 EXPECT_CALL(*audio_input_listener_
,
273 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
275 message_loop_
->RunUntilIdle();
277 // Access a non-opened device.
278 // This should fail and return an empty StreamDeviceInfo.
279 int invalid_session_id
= session_id
+ 1;
280 const StreamDeviceInfo
* info
=
281 manager_
->GetOpenedDeviceInfoById(invalid_session_id
);
284 manager_
->Close(session_id
);
285 EXPECT_CALL(*audio_input_listener_
,
286 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
288 message_loop_
->RunUntilIdle();
291 } // namespace content