c2963eefd362d3785e897d121e811073be5240b1
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / audio_input_device_manager_unittest.cc
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.
4
5 #include <string>
6
7 #include "base/bind.h"
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"
18
19 using testing::_;
20 using testing::InSequence;
21 using testing::SaveArg;
22 using testing::Return;
23
24 namespace content {
25
26 class MockAudioInputDeviceManagerListener
27     : public MediaStreamProviderListener {
28  public:
29   MockAudioInputDeviceManagerListener() {}
30   virtual ~MockAudioInputDeviceManagerListener() {}
31
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));
37
38   StreamDeviceInfoArray devices_;
39
40  private:
41   DISALLOW_COPY_AND_ASSIGN(MockAudioInputDeviceManagerListener);
42 };
43
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
49 #else
50 #define MAYBE_AudioInputDeviceManagerTest AudioInputDeviceManagerTest
51 #endif
52
53 class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
54  public:
55   MAYBE_AudioInputDeviceManagerTest() {}
56
57  protected:
58   virtual 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)));
69     event.Wait();
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());
75
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, _))
80         .Times(1)
81         .WillOnce(SaveArg<1>(&devices_));
82
83     // Wait until we get the list.
84     message_loop_->RunUntilIdle();
85   }
86
87   virtual void TearDown() OVERRIDE {
88     manager_->Unregister();
89     io_thread_.reset();
90   }
91
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_;
98
99  private:
100   DISALLOW_COPY_AND_ASSIGN(MAYBE_AudioInputDeviceManagerTest);
101 };
102
103 // Opens and closes the devices.
104 TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) {
105
106   ASSERT_FALSE(devices_.empty());
107
108   InSequence s;
109
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);
114
115     // Expected mock call with expected return value.
116     EXPECT_CALL(*audio_input_listener_,
117                 Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
118         .Times(1);
119     // Waits for the callback.
120     message_loop_->RunUntilIdle();
121
122     manager_->Close(session_id);
123     EXPECT_CALL(*audio_input_listener_,
124                 Closed(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
125         .Times(1);
126
127     // Waits for the callback.
128     message_loop_->RunUntilIdle();
129   }
130 }
131
132 // Opens multiple devices at one time and closes them later.
133 TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) {
134   ASSERT_FALSE(devices_.empty());
135
136   InSequence s;
137
138   int index = 0;
139   scoped_ptr<int[]> session_id(new int[devices_.size()]);
140
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);
146
147     // Expected mock call with expected returned value.
148     EXPECT_CALL(*audio_input_listener_,
149                 Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id[index]))
150         .Times(1);
151
152     // Waits for the callback.
153     message_loop_->RunUntilIdle();
154   }
155
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]);
160     }
161   }
162
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]))
168         .Times(1);
169
170     // Waits for the callback.
171     message_loop_->RunUntilIdle();
172   }
173 }
174
175 // Opens a non-existing device.
176 TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) {
177   InSequence s;
178
179   MediaStreamType stream_type = MEDIA_DEVICE_AUDIO_CAPTURE;
180   std::string device_name("device_doesnt_exist");
181   std::string device_id("id_doesnt_exist");
182   int sample_rate(0);
183   int channel_config(0);
184   StreamDeviceInfo dummy_device(
185       stream_type, device_name, device_id, sample_rate, channel_config, 2048);
186
187   int session_id = manager_->Open(dummy_device);
188   EXPECT_CALL(*audio_input_listener_,
189               Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
190       .Times(1);
191
192   // Waits for the callback.
193   message_loop_->RunUntilIdle();
194 }
195
196 // Opens default device twice.
197 TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) {
198   ASSERT_FALSE(devices_.empty());
199
200   InSequence s;
201
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());
205
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))
210       .Times(1);
211   EXPECT_CALL(*audio_input_listener_,
212               Opened(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
213       .Times(1);
214   // Waits for the callback.
215   message_loop_->RunUntilIdle();
216
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))
221       .Times(1);
222   EXPECT_CALL(*audio_input_listener_,
223               Closed(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
224       .Times(1);
225   // Waits for the callback.
226   message_loop_->RunUntilIdle();
227 }
228
229 // Accesses then closes the sessions after opening the devices.
230 TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) {
231   ASSERT_FALSE(devices_.empty());
232
233   InSequence s;
234
235   int index = 0;
236   scoped_ptr<int[]> session_id(new int[devices_.size()]);
237
238   // Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
239   // for each device.
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]))
247         .Times(1);
248     message_loop_->RunUntilIdle();
249
250     const StreamDeviceInfo* info = manager_->GetOpenedDeviceInfoById(
251         session_id[index]);
252     DCHECK(info);
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]))
257         .Times(1);
258     message_loop_->RunUntilIdle();
259   }
260 }
261
262 // Access an invalid session.
263 TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessInvalidSession) {
264   InSequence s;
265
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))
271       .Times(1);
272   message_loop_->RunUntilIdle();
273
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);
279   DCHECK(!info);
280
281   manager_->Close(session_id);
282   EXPECT_CALL(*audio_input_listener_,
283               Closed(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
284       .Times(1);
285   message_loop_->RunUntilIdle();
286 }
287
288 }  // namespace content