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/location.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
15 #include "content/public/common/media_stream_request.h"
16 #include "media/audio/audio_manager_base.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::InSequence
;
22 using testing::SaveArg
;
23 using testing::Return
;
27 class MockAudioInputDeviceManagerListener
28 : public MediaStreamProviderListener
{
30 MockAudioInputDeviceManagerListener() {}
31 virtual ~MockAudioInputDeviceManagerListener() {}
33 MOCK_METHOD2(Opened
, void(MediaStreamType
, const int));
34 MOCK_METHOD2(Closed
, void(MediaStreamType
, const int));
35 MOCK_METHOD2(DevicesEnumerated
, void(MediaStreamType
,
36 const StreamDeviceInfoArray
&));
37 MOCK_METHOD2(Aborted
, void(MediaStreamType
, int));
39 StreamDeviceInfoArray devices_
;
42 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener
);
45 // TODO(henrika): there are special restrictions for Android since
46 // AudioInputDeviceManager::Open() must be called on the audio thread.
47 // This test suite must be modified to run on Android.
48 #if defined(OS_ANDROID)
49 #define MAYBE_AudioInputDeviceManagerTest DISABLED_AudioInputDeviceManagerTest
51 #define MAYBE_AudioInputDeviceManagerTest AudioInputDeviceManagerTest
54 class MAYBE_AudioInputDeviceManagerTest
: public testing::Test
{
56 MAYBE_AudioInputDeviceManagerTest() {}
59 void SetUp() override
{
60 // The test must run on Browser::IO.
61 message_loop_
.reset(new base::MessageLoopForIO
);
62 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
63 message_loop_
.get()));
64 audio_manager_
.reset(media::AudioManager::CreateForTesting());
65 // Wait for audio thread initialization to complete. Otherwise the
66 // enumeration type may not have been set yet.
67 base::WaitableEvent
event(false, false);
68 audio_manager_
->GetTaskRunner()->PostTask(FROM_HERE
, base::Bind(
69 &base::WaitableEvent::Signal
, base::Unretained(&event
)));
71 manager_
= new AudioInputDeviceManager(audio_manager_
.get());
72 manager_
->UseFakeDevice();
73 audio_input_listener_
.reset(new MockAudioInputDeviceManagerListener());
74 manager_
->Register(audio_input_listener_
.get(),
75 message_loop_
->task_runner().get());
77 // Gets the enumerated device list from the AudioInputDeviceManager.
78 manager_
->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE
);
79 EXPECT_CALL(*audio_input_listener_
,
80 DevicesEnumerated(MEDIA_DEVICE_AUDIO_CAPTURE
, _
))
82 .WillOnce(SaveArg
<1>(&devices_
));
84 // Wait until we get the list.
85 message_loop_
->RunUntilIdle();
88 void TearDown() override
{
89 manager_
->Unregister();
93 scoped_ptr
<base::MessageLoop
> message_loop_
;
94 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
95 scoped_refptr
<AudioInputDeviceManager
> manager_
;
96 scoped_ptr
<MockAudioInputDeviceManagerListener
> audio_input_listener_
;
97 scoped_ptr
<media::AudioManager
> audio_manager_
;
98 StreamDeviceInfoArray devices_
;
101 DISALLOW_COPY_AND_ASSIGN(MAYBE_AudioInputDeviceManagerTest
);
104 // Opens and closes the devices.
105 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenAndCloseDevice
) {
107 ASSERT_FALSE(devices_
.empty());
111 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
112 iter
!= devices_
.end(); ++iter
) {
113 // Opens/closes the devices.
114 int session_id
= manager_
->Open(*iter
);
116 // Expected mock call with expected return value.
117 EXPECT_CALL(*audio_input_listener_
,
118 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
120 // Waits for the callback.
121 message_loop_
->RunUntilIdle();
123 manager_
->Close(session_id
);
124 EXPECT_CALL(*audio_input_listener_
,
125 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
128 // Waits for the callback.
129 message_loop_
->RunUntilIdle();
133 // Opens multiple devices at one time and closes them later.
134 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenMultipleDevices
) {
135 ASSERT_FALSE(devices_
.empty());
140 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
142 // Opens the devices in a loop.
143 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
144 iter
!= devices_
.end(); ++iter
, ++index
) {
145 // Opens the devices.
146 session_id
[index
] = manager_
->Open(*iter
);
148 // Expected mock call with expected returned value.
149 EXPECT_CALL(*audio_input_listener_
,
150 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
153 // Waits for the callback.
154 message_loop_
->RunUntilIdle();
157 // Checks if the session_ids are unique.
158 for (size_t i
= 0; i
< devices_
.size() - 1; ++i
) {
159 for (size_t k
= i
+ 1; k
< devices_
.size(); ++k
) {
160 EXPECT_TRUE(session_id
[i
] != session_id
[k
]);
164 for (size_t i
= 0; i
< devices_
.size(); ++i
) {
165 // Closes the devices.
166 manager_
->Close(session_id
[i
]);
167 EXPECT_CALL(*audio_input_listener_
,
168 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[i
]))
171 // Waits for the callback.
172 message_loop_
->RunUntilIdle();
176 // Opens a non-existing device.
177 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenNotExistingDevice
) {
180 MediaStreamType stream_type
= MEDIA_DEVICE_AUDIO_CAPTURE
;
181 std::string
device_name("device_doesnt_exist");
182 std::string
device_id("id_doesnt_exist");
184 int channel_config(0);
185 StreamDeviceInfo
dummy_device(
186 stream_type
, device_name
, device_id
, sample_rate
, channel_config
, 2048);
188 int session_id
= manager_
->Open(dummy_device
);
189 EXPECT_CALL(*audio_input_listener_
,
190 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
193 // Waits for the callback.
194 message_loop_
->RunUntilIdle();
197 // Opens default device twice.
198 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenDeviceTwice
) {
199 ASSERT_FALSE(devices_
.empty());
203 // Opens and closes the default device twice.
204 int first_session_id
= manager_
->Open(devices_
.front());
205 int second_session_id
= manager_
->Open(devices_
.front());
207 // Expected mock calls with expected returned values.
208 EXPECT_NE(first_session_id
, second_session_id
);
209 EXPECT_CALL(*audio_input_listener_
,
210 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
212 EXPECT_CALL(*audio_input_listener_
,
213 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
215 // Waits for the callback.
216 message_loop_
->RunUntilIdle();
218 manager_
->Close(first_session_id
);
219 manager_
->Close(second_session_id
);
220 EXPECT_CALL(*audio_input_listener_
,
221 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
223 EXPECT_CALL(*audio_input_listener_
,
224 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
226 // Waits for the callback.
227 message_loop_
->RunUntilIdle();
230 // Accesses then closes the sessions after opening the devices.
231 TEST_F(MAYBE_AudioInputDeviceManagerTest
, AccessAndCloseSession
) {
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(MAYBE_AudioInputDeviceManagerTest
, AccessInvalidSession
) {
267 // Opens the first device.
268 StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
269 int session_id
= manager_
->Open(*iter
);
270 EXPECT_CALL(*audio_input_listener_
,
271 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
273 message_loop_
->RunUntilIdle();
275 // Access a non-opened device.
276 // This should fail and return an empty StreamDeviceInfo.
277 int invalid_session_id
= session_id
+ 1;
278 const StreamDeviceInfo
* info
=
279 manager_
->GetOpenedDeviceInfoById(invalid_session_id
);
282 manager_
->Close(session_id
);
283 EXPECT_CALL(*audio_input_listener_
,
284 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
286 message_loop_
->RunUntilIdle();
289 } // namespace content