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() {}
58 void SetUp() override
{
59 // The test must run on Browser::IO.
60 message_loop_
.reset(new base::MessageLoopForIO
);
61 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
62 message_loop_
.get()));
63 audio_manager_
.reset(media::AudioManager::CreateForTesting());
64 // Wait for audio thread initialization to complete. Otherwise the
65 // enumeration type may not have been set yet.
66 base::WaitableEvent
event(false, false);
67 audio_manager_
->GetTaskRunner()->PostTask(FROM_HERE
, base::Bind(
68 &base::WaitableEvent::Signal
, base::Unretained(&event
)));
70 manager_
= new AudioInputDeviceManager(audio_manager_
.get());
71 manager_
->UseFakeDevice();
72 audio_input_listener_
.reset(new MockAudioInputDeviceManagerListener());
73 manager_
->Register(audio_input_listener_
.get(),
74 message_loop_
->message_loop_proxy().get());
76 // Gets the enumerated device list from the AudioInputDeviceManager.
77 manager_
->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE
);
78 EXPECT_CALL(*audio_input_listener_
,
79 DevicesEnumerated(MEDIA_DEVICE_AUDIO_CAPTURE
, _
))
81 .WillOnce(SaveArg
<1>(&devices_
));
83 // Wait until we get the list.
84 message_loop_
->RunUntilIdle();
87 void TearDown() override
{
88 manager_
->Unregister();
92 scoped_ptr
<base::MessageLoop
> message_loop_
;
93 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
94 scoped_refptr
<AudioInputDeviceManager
> manager_
;
95 scoped_ptr
<MockAudioInputDeviceManagerListener
> audio_input_listener_
;
96 scoped_ptr
<media::AudioManager
> audio_manager_
;
97 StreamDeviceInfoArray devices_
;
100 DISALLOW_COPY_AND_ASSIGN(MAYBE_AudioInputDeviceManagerTest
);
103 // Opens and closes the devices.
104 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenAndCloseDevice
) {
106 ASSERT_FALSE(devices_
.empty());
110 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
111 iter
!= devices_
.end(); ++iter
) {
112 // Opens/closes the devices.
113 int session_id
= manager_
->Open(*iter
);
115 // Expected mock call with expected return value.
116 EXPECT_CALL(*audio_input_listener_
,
117 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
119 // Waits for the callback.
120 message_loop_
->RunUntilIdle();
122 manager_
->Close(session_id
);
123 EXPECT_CALL(*audio_input_listener_
,
124 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
127 // Waits for the callback.
128 message_loop_
->RunUntilIdle();
132 // Opens multiple devices at one time and closes them later.
133 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenMultipleDevices
) {
134 ASSERT_FALSE(devices_
.empty());
139 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
141 // Opens the devices in a loop.
142 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
143 iter
!= devices_
.end(); ++iter
, ++index
) {
144 // Opens the devices.
145 session_id
[index
] = manager_
->Open(*iter
);
147 // Expected mock call with expected returned value.
148 EXPECT_CALL(*audio_input_listener_
,
149 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
152 // Waits for the callback.
153 message_loop_
->RunUntilIdle();
156 // Checks if the session_ids are unique.
157 for (size_t i
= 0; i
< devices_
.size() - 1; ++i
) {
158 for (size_t k
= i
+ 1; k
< devices_
.size(); ++k
) {
159 EXPECT_TRUE(session_id
[i
] != session_id
[k
]);
163 for (size_t i
= 0; i
< devices_
.size(); ++i
) {
164 // Closes the devices.
165 manager_
->Close(session_id
[i
]);
166 EXPECT_CALL(*audio_input_listener_
,
167 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[i
]))
170 // Waits for the callback.
171 message_loop_
->RunUntilIdle();
175 // Opens a non-existing device.
176 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenNotExistingDevice
) {
179 MediaStreamType stream_type
= MEDIA_DEVICE_AUDIO_CAPTURE
;
180 std::string
device_name("device_doesnt_exist");
181 std::string
device_id("id_doesnt_exist");
183 int channel_config(0);
184 StreamDeviceInfo
dummy_device(
185 stream_type
, device_name
, device_id
, sample_rate
, channel_config
, 2048);
187 int session_id
= manager_
->Open(dummy_device
);
188 EXPECT_CALL(*audio_input_listener_
,
189 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
192 // Waits for the callback.
193 message_loop_
->RunUntilIdle();
196 // Opens default device twice.
197 TEST_F(MAYBE_AudioInputDeviceManagerTest
, OpenDeviceTwice
) {
198 ASSERT_FALSE(devices_
.empty());
202 // Opens and closes the default device twice.
203 int first_session_id
= manager_
->Open(devices_
.front());
204 int second_session_id
= manager_
->Open(devices_
.front());
206 // Expected mock calls with expected returned values.
207 EXPECT_NE(first_session_id
, second_session_id
);
208 EXPECT_CALL(*audio_input_listener_
,
209 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
211 EXPECT_CALL(*audio_input_listener_
,
212 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
214 // Waits for the callback.
215 message_loop_
->RunUntilIdle();
217 manager_
->Close(first_session_id
);
218 manager_
->Close(second_session_id
);
219 EXPECT_CALL(*audio_input_listener_
,
220 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, first_session_id
))
222 EXPECT_CALL(*audio_input_listener_
,
223 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, second_session_id
))
225 // Waits for the callback.
226 message_loop_
->RunUntilIdle();
229 // Accesses then closes the sessions after opening the devices.
230 TEST_F(MAYBE_AudioInputDeviceManagerTest
, AccessAndCloseSession
) {
231 ASSERT_FALSE(devices_
.empty());
236 scoped_ptr
<int[]> session_id(new int[devices_
.size()]);
238 // Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
240 for (StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
241 iter
!= devices_
.end(); ++iter
, ++index
) {
242 // Note that no DeviceStopped() notification for Event Handler as we have
243 // stopped the device before calling close.
244 session_id
[index
] = manager_
->Open(*iter
);
245 EXPECT_CALL(*audio_input_listener_
,
246 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
248 message_loop_
->RunUntilIdle();
250 const StreamDeviceInfo
* info
= manager_
->GetOpenedDeviceInfoById(
253 EXPECT_EQ(iter
->device
.id
, info
->device
.id
);
254 manager_
->Close(session_id
[index
]);
255 EXPECT_CALL(*audio_input_listener_
,
256 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
[index
]))
258 message_loop_
->RunUntilIdle();
262 // Access an invalid session.
263 TEST_F(MAYBE_AudioInputDeviceManagerTest
, AccessInvalidSession
) {
266 // Opens the first device.
267 StreamDeviceInfoArray::const_iterator iter
= devices_
.begin();
268 int session_id
= manager_
->Open(*iter
);
269 EXPECT_CALL(*audio_input_listener_
,
270 Opened(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
272 message_loop_
->RunUntilIdle();
274 // Access a non-opened device.
275 // This should fail and return an empty StreamDeviceInfo.
276 int invalid_session_id
= session_id
+ 1;
277 const StreamDeviceInfo
* info
=
278 manager_
->GetOpenedDeviceInfoById(invalid_session_id
);
281 manager_
->Close(session_id
);
282 EXPECT_CALL(*audio_input_listener_
,
283 Closed(MEDIA_DEVICE_AUDIO_CAPTURE
, session_id
))
285 message_loop_
->RunUntilIdle();
288 } // namespace content