Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / audio_input_device_manager_unittest.cc
blob5b4aa55960ff0ed2cf5f74953c737d050c39fdcb
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.
5 #include <string>
7 #include "base/bind.h"
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"
18 using testing::_;
19 using testing::InSequence;
20 using testing::SaveArg;
21 using testing::Return;
23 namespace content {
25 class MockAudioInputDeviceManagerListener
26 : public MediaStreamProviderListener {
27 public:
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_;
39 private:
40 DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener);
43 class AudioInputDeviceManagerTest : public testing::Test {
44 public:
45 AudioInputDeviceManagerTest() {}
47 // Returns true iff machine has an audio input device.
48 bool CanRunAudioInputDeviceTests() {
49 return audio_manager_->HasAudioInputDevices();
52 protected:
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, _))
68 .Times(1)
69 .WillOnce(SaveArg<1>(&devices_));
71 // Wait until we get the list.
72 message_loop_->RunUntilIdle();
75 virtual void TearDown() OVERRIDE {
76 manager_->Unregister();
77 io_thread_.reset();
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_;
87 private:
88 DISALLOW_COPY_AND_ASSIGN(AudioInputDeviceManagerTest);
91 // Opens and closes the devices.
92 TEST_F(AudioInputDeviceManagerTest, OpenAndCloseDevice) {
93 if (!CanRunAudioInputDeviceTests())
94 return;
96 ASSERT_FALSE(devices_.empty());
98 InSequence s;
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))
108 .Times(1);
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))
115 .Times(1);
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())
125 return;
127 ASSERT_FALSE(devices_.empty());
129 InSequence s;
131 int index = 0;
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]))
143 .Times(1);
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]))
161 .Times(1);
163 // Waits for the callback.
164 message_loop_->RunUntilIdle();
168 // Opens a non-existing device.
169 TEST_F(AudioInputDeviceManagerTest, OpenNotExistingDevice) {
170 if (!CanRunAudioInputDeviceTests())
171 return;
172 InSequence s;
174 MediaStreamType stream_type = MEDIA_DEVICE_AUDIO_CAPTURE;
175 std::string device_name("device_doesnt_exist");
176 std::string device_id("id_doesnt_exist");
177 int sample_rate(0);
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))
185 .Times(1);
187 // Waits for the callback.
188 message_loop_->RunUntilIdle();
191 // Opens default device twice.
192 TEST_F(AudioInputDeviceManagerTest, OpenDeviceTwice) {
193 if (!CanRunAudioInputDeviceTests())
194 return;
196 ASSERT_FALSE(devices_.empty());
198 InSequence s;
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))
208 .Times(1);
209 EXPECT_CALL(*audio_input_listener_,
210 Opened(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
211 .Times(1);
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))
219 .Times(1);
220 EXPECT_CALL(*audio_input_listener_,
221 Closed(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
222 .Times(1);
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())
230 return;
232 ASSERT_FALSE(devices_.empty());
234 InSequence s;
236 int index = 0;
237 scoped_ptr<int[]> session_id(new int[devices_.size()]);
239 // Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
240 // for each device.
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]))
248 .Times(1);
249 message_loop_->RunUntilIdle();
251 const StreamDeviceInfo* info = manager_->GetOpenedDeviceInfoById(
252 session_id[index]);
253 DCHECK(info);
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]))
258 .Times(1);
259 message_loop_->RunUntilIdle();
263 // Access an invalid session.
264 TEST_F(AudioInputDeviceManagerTest, AccessInvalidSession) {
265 if (!CanRunAudioInputDeviceTests())
266 return;
267 InSequence s;
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))
274 .Times(1);
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);
282 DCHECK(!info);
284 manager_->Close(session_id);
285 EXPECT_CALL(*audio_input_listener_,
286 Closed(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
287 .Times(1);
288 message_loop_->RunUntilIdle();
291 } // namespace content