Implement getMediaDevices.
[chromium-blink-merge.git] / content / renderer / media / media_stream_impl_unittest.cc
blob7db70db61c1ec0aebccc8840c6e3368b0afa22f6
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 "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/child/child_process.h"
9 #include "content/renderer/media/media_stream.h"
10 #include "content/renderer/media/media_stream_impl.h"
11 #include "content/renderer/media/media_stream_track.h"
12 #include "content/renderer/media/mock_media_stream_dispatcher.h"
13 #include "content/renderer/media/mock_media_stream_video_source.h"
14 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
17 #include "third_party/WebKit/public/platform/WebMediaStream.h"
18 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
19 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
20 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/platform/WebVector.h"
23 namespace content {
25 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource {
26 public:
27 MockMediaStreamVideoCapturerSource(
28 const StreamDeviceInfo& device,
29 const SourceStoppedCallback& stop_callback,
30 PeerConnectionDependencyFactory* factory)
31 : MockMediaStreamVideoSource(false) {
32 SetDeviceInfo(device);
33 SetStopCallback(stop_callback);
37 class MediaStreamImplUnderTest : public MediaStreamImpl {
38 public:
39 enum RequestState {
40 REQUEST_NOT_STARTED,
41 REQUEST_NOT_COMPLETE,
42 REQUEST_SUCCEEDED,
43 REQUEST_FAILED,
46 MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
47 PeerConnectionDependencyFactory* dependency_factory)
48 : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
49 state_(REQUEST_NOT_STARTED),
50 result_(NUM_MEDIA_REQUEST_RESULTS),
51 factory_(dependency_factory),
52 video_source_(NULL) {
55 void RequestUserMedia() {
56 blink::WebUserMediaRequest user_media_request;
57 state_ = REQUEST_NOT_COMPLETE;
58 requestUserMedia(user_media_request);
61 void RequestMediaDevices() {
62 blink::WebMediaDevicesRequest media_devices_request;
63 state_ = REQUEST_NOT_COMPLETE;
64 requestMediaDevices(media_devices_request);
67 virtual void GetUserMediaRequestSucceeded(
68 const blink::WebMediaStream& stream,
69 blink::WebUserMediaRequest* request_info) OVERRIDE {
70 last_generated_stream_ = stream;
71 state_ = REQUEST_SUCCEEDED;
74 virtual void GetUserMediaRequestFailed(
75 blink::WebUserMediaRequest* request_info,
76 content::MediaStreamRequestResult result) OVERRIDE {
77 last_generated_stream_.reset();
78 state_ = REQUEST_FAILED;
79 result_ = result;
82 virtual void EnumerateDevicesSucceded(
83 blink::WebMediaDevicesRequest* request,
84 blink::WebVector<blink::WebMediaDeviceInfo>& devices) OVERRIDE {
85 state_ = REQUEST_SUCCEEDED;
86 last_devices_ = devices;
89 virtual MediaStreamVideoSource* CreateVideoSource(
90 const StreamDeviceInfo& device,
91 const MediaStreamSource::SourceStoppedCallback& stop_callback) OVERRIDE {
92 video_source_ = new MockMediaStreamVideoCapturerSource(device,
93 stop_callback,
94 factory_);
95 return video_source_;
98 const blink::WebMediaStream& last_generated_stream() {
99 return last_generated_stream_;
102 const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() {
103 return last_devices_;
106 void ClearLastGeneratedStream() {
107 last_generated_stream_.reset();
110 MockMediaStreamVideoCapturerSource* last_created_video_source() const {
111 return video_source_;
114 RequestState request_state() const { return state_; }
115 content::MediaStreamRequestResult error_reason() const { return result_; }
117 private:
118 blink::WebMediaStream last_generated_stream_;
119 RequestState state_;
120 content::MediaStreamRequestResult result_;
121 blink::WebVector<blink::WebMediaDeviceInfo> last_devices_;
122 PeerConnectionDependencyFactory* factory_;
123 MockMediaStreamVideoCapturerSource* video_source_;
126 class MediaStreamImplTest : public ::testing::Test {
127 public:
128 virtual void SetUp() {
129 // Create our test object.
130 child_process_.reset(new ChildProcess());
131 ms_dispatcher_.reset(new MockMediaStreamDispatcher());
132 dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
133 ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
134 dependency_factory_.get()));
137 blink::WebMediaStream RequestLocalMediaStream() {
138 ms_impl_->RequestUserMedia();
139 FakeMediaStreamDispatcherRequestUserMediaComplete();
140 StartMockedVideoSource();
142 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
143 ms_impl_->request_state());
145 blink::WebMediaStream desc = ms_impl_->last_generated_stream();
146 content::MediaStream* native_stream =
147 content::MediaStream::GetMediaStream(desc);
148 if (!native_stream) {
149 ADD_FAILURE();
150 return desc;
153 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
154 desc.audioTracks(audio_tracks);
155 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
156 desc.videoTracks(video_tracks);
158 EXPECT_EQ(1u, audio_tracks.size());
159 EXPECT_EQ(1u, video_tracks.size());
160 EXPECT_NE(audio_tracks[0].id(), video_tracks[0].id());
161 return desc;
164 void FakeMediaStreamDispatcherRequestUserMediaComplete() {
165 // Audio request ID is used as the shared request ID.
166 ms_impl_->OnStreamGenerated(ms_dispatcher_->audio_request_id(),
167 ms_dispatcher_->stream_label(),
168 ms_dispatcher_->audio_array(),
169 ms_dispatcher_->video_array());
172 void FakeMediaStreamDispatcherRequestMediaDevicesComplete() {
173 ms_impl_->OnDevicesEnumerated(ms_dispatcher_->audio_request_id(),
174 ms_dispatcher_->audio_array());
175 ms_impl_->OnDevicesEnumerated(ms_dispatcher_->video_request_id(),
176 ms_dispatcher_->video_array());
179 void StartMockedVideoSource() {
180 MockMediaStreamVideoCapturerSource* video_source =
181 ms_impl_->last_created_video_source();
182 if (video_source->SourceHasAttemptedToStart())
183 video_source->StartMockedSource();
186 void FailToStartMockedVideoSource() {
187 MockMediaStreamVideoCapturerSource* video_source =
188 ms_impl_->last_created_video_source();
189 if (video_source->SourceHasAttemptedToStart())
190 video_source->FailToStartMockedSource();
193 void FailToCreateNextAudioCapturer() {
194 dependency_factory_->FailToCreateNextAudioCapturer();
197 protected:
198 base::MessageLoop message_loop_;
199 scoped_ptr<ChildProcess> child_process_;
200 scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
201 scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
202 scoped_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
205 TEST_F(MediaStreamImplTest, GenerateMediaStream) {
206 // Generate a stream with both audio and video.
207 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
210 // Test that the same source object is used if two MediaStreams are generated
211 // using the same source.
212 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithSameSource) {
213 blink::WebMediaStream desc1 = RequestLocalMediaStream();
214 blink::WebMediaStream desc2 = RequestLocalMediaStream();
216 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
217 desc1.videoTracks(desc1_video_tracks);
218 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
219 desc2.videoTracks(desc2_video_tracks);
220 EXPECT_EQ(desc1_video_tracks[0].source().id(),
221 desc2_video_tracks[0].source().id());
223 EXPECT_EQ(desc1_video_tracks[0].source().extraData(),
224 desc2_video_tracks[0].source().extraData());
226 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
227 desc1.audioTracks(desc1_audio_tracks);
228 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
229 desc2.audioTracks(desc2_audio_tracks);
230 EXPECT_EQ(desc1_audio_tracks[0].source().id(),
231 desc2_audio_tracks[0].source().id());
233 EXPECT_EQ(desc1_audio_tracks[0].source().extraData(),
234 desc2_audio_tracks[0].source().extraData());
237 // Test that the same source object is not used if two MediaStreams are
238 // generated using different sources.
239 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
240 blink::WebMediaStream desc1 = RequestLocalMediaStream();
241 // Make sure another device is selected (another |session_id|) in the next
242 // gUM request.
243 ms_dispatcher_->IncrementSessionId();
244 blink::WebMediaStream desc2 = RequestLocalMediaStream();
246 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
247 desc1.videoTracks(desc1_video_tracks);
248 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
249 desc2.videoTracks(desc2_video_tracks);
250 EXPECT_NE(desc1_video_tracks[0].source().id(),
251 desc2_video_tracks[0].source().id());
253 EXPECT_NE(desc1_video_tracks[0].source().extraData(),
254 desc2_video_tracks[0].source().extraData());
256 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
257 desc1.audioTracks(desc1_audio_tracks);
258 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
259 desc2.audioTracks(desc2_audio_tracks);
260 EXPECT_NE(desc1_audio_tracks[0].source().id(),
261 desc2_audio_tracks[0].source().id());
263 EXPECT_NE(desc1_audio_tracks[0].source().extraData(),
264 desc2_audio_tracks[0].source().extraData());
267 TEST_F(MediaStreamImplTest, StopLocalTracks) {
268 // Generate a stream with both audio and video.
269 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
271 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
272 mixed_desc.audioTracks(audio_tracks);
273 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
274 audio_track->Stop();
275 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
277 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
278 mixed_desc.videoTracks(video_tracks);
279 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
280 video_track->Stop();
281 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
284 // This test that a source is not stopped even if the tracks in a
285 // MediaStream is stopped if there are two MediaStreams with tracks using the
286 // same device. The source is stopped
287 // if there are no more MediaStream tracks using the device.
288 TEST_F(MediaStreamImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
289 // Generate a stream with both audio and video.
290 blink::WebMediaStream desc1 = RequestLocalMediaStream();
291 blink::WebMediaStream desc2 = RequestLocalMediaStream();
293 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1;
294 desc1.audioTracks(audio_tracks1);
295 MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
296 audio_track1->Stop();
297 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
299 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
300 desc2.audioTracks(audio_tracks2);
301 MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
302 audio_track2->Stop();
303 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
305 blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
306 desc1.videoTracks(video_tracks1);
307 MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
308 video_track1->Stop();
309 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
311 blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
312 desc2.videoTracks(video_tracks2);
313 MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
314 video_track2->Stop();
315 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
318 TEST_F(MediaStreamImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
319 // Generate a stream with both audio and video.
320 RequestLocalMediaStream();
321 // Makes sure the test itself don't hold a reference to the created
322 // MediaStream.
323 ms_impl_->ClearLastGeneratedStream();
325 // Expect the sources to be stopped when the MediaStream goes out of scope.
326 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
327 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
330 // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
331 // In the unit test the owning frame is NULL.
332 TEST_F(MediaStreamImplTest, FrameWillClose) {
333 // Test a stream with both audio and video.
334 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
335 blink::WebMediaStream desc2 = RequestLocalMediaStream();
337 // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
338 // In the unit test the owning frame is NULL.
339 ms_impl_->FrameWillClose(NULL);
340 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
341 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
344 // This test what happens if a video source to a MediaSteam fails to start.
345 TEST_F(MediaStreamImplTest, MediaVideoSourceFailToStart) {
346 ms_impl_->RequestUserMedia();
347 FakeMediaStreamDispatcherRequestUserMediaComplete();
348 FailToStartMockedVideoSource();
349 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
350 ms_impl_->request_state());
351 EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
352 ms_impl_->error_reason());
353 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
354 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
355 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
358 // This test what happens if an audio source fail to initialize.
359 TEST_F(MediaStreamImplTest, MediaAudioSourceFailToInitialize) {
360 FailToCreateNextAudioCapturer();
361 ms_impl_->RequestUserMedia();
362 FakeMediaStreamDispatcherRequestUserMediaComplete();
363 StartMockedVideoSource();
364 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
365 ms_impl_->request_state());
366 EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
367 ms_impl_->error_reason());
368 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
369 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
370 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
373 // This test what happens if MediaStreamImpl is deleted before a source has
374 // started.
375 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
376 ms_impl_->RequestUserMedia();
377 FakeMediaStreamDispatcherRequestUserMediaComplete();
378 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
379 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
380 ms_impl_->request_state());
381 ms_impl_.reset();
384 // This test what happens if the WebFrame is closed while the MediaStream is
385 // being generated by the MediaStreamDispatcher.
386 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
387 ms_impl_->RequestUserMedia();
388 ms_impl_->FrameWillClose(NULL);
389 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
390 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
391 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
392 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
393 ms_impl_->request_state());
396 // This test what happens if the WebFrame is closed while the sources are being
397 // started.
398 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
399 ms_impl_->RequestUserMedia();
400 FakeMediaStreamDispatcherRequestUserMediaComplete();
401 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
402 ms_impl_->FrameWillClose(NULL);
403 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
404 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
405 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
406 ms_impl_->request_state());
409 // This test what happens if stop is called on a track after the frame has
410 // been reloaded.
411 TEST_F(MediaStreamImplTest, StopTrackAfterReload) {
412 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
413 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
414 ms_impl_->FrameWillClose(NULL);
415 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
416 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
418 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
419 mixed_desc.audioTracks(audio_tracks);
420 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
421 audio_track->Stop();
422 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
424 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
425 mixed_desc.videoTracks(video_tracks);
426 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
427 video_track->Stop();
428 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
431 TEST_F(MediaStreamImplTest, EnumerateMediaDevices) {
432 ms_impl_->RequestMediaDevices();
433 FakeMediaStreamDispatcherRequestMediaDevicesComplete();
435 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
436 ms_impl_->request_state());
438 EXPECT_FALSE(ms_impl_->last_devices()[0].deviceId().isEmpty());
439 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput,
440 ms_impl_->last_devices()[0].kind());
441 EXPECT_FALSE(ms_impl_->last_devices()[0].label().isEmpty());
443 EXPECT_FALSE(ms_impl_->last_devices()[1].deviceId().isEmpty());
444 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
445 ms_impl_->last_devices()[1].kind());
446 EXPECT_FALSE(ms_impl_->last_devices()[1].label().isEmpty());
449 } // namespace content