Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / media / media_stream_impl_unittest.cc
blobc94a48762028b18b641913c664c7c6020213a4f4
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(
47 PeerConnectionDependencyFactory* dependency_factory,
48 scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher)
49 : MediaStreamImpl(
50 NULL, dependency_factory, media_stream_dispatcher.Pass()),
51 state_(REQUEST_NOT_STARTED),
52 result_(NUM_MEDIA_REQUEST_RESULTS),
53 result_name_(""),
54 factory_(dependency_factory),
55 video_source_(NULL) {
58 void RequestUserMedia() {
59 blink::WebUserMediaRequest user_media_request;
60 state_ = REQUEST_NOT_COMPLETE;
61 requestUserMedia(user_media_request);
64 void RequestMediaDevices() {
65 blink::WebMediaDevicesRequest media_devices_request;
66 state_ = REQUEST_NOT_COMPLETE;
67 requestMediaDevices(media_devices_request);
70 virtual void GetUserMediaRequestSucceeded(
71 const blink::WebMediaStream& stream,
72 blink::WebUserMediaRequest* request_info) OVERRIDE {
73 last_generated_stream_ = stream;
74 state_ = REQUEST_SUCCEEDED;
77 virtual void GetUserMediaRequestFailed(
78 blink::WebUserMediaRequest* request_info,
79 content::MediaStreamRequestResult result) OVERRIDE {
80 last_generated_stream_.reset();
81 state_ = REQUEST_FAILED;
82 result_ = result;
85 virtual void GetUserMediaRequestTrackStartedFailed(
86 blink::WebUserMediaRequest* request_info,
87 MediaStreamRequestResult result,
88 const blink::WebString& result_name) OVERRIDE {
89 last_generated_stream_.reset();
90 state_ = REQUEST_FAILED;
91 result_ = result;
92 result_name_ = result_name;
95 virtual void EnumerateDevicesSucceded(
96 blink::WebMediaDevicesRequest* request,
97 blink::WebVector<blink::WebMediaDeviceInfo>& devices) OVERRIDE {
98 state_ = REQUEST_SUCCEEDED;
99 last_devices_ = devices;
102 virtual MediaStreamVideoSource* CreateVideoSource(
103 const StreamDeviceInfo& device,
104 const MediaStreamSource::SourceStoppedCallback& stop_callback) OVERRIDE {
105 video_source_ = new MockMediaStreamVideoCapturerSource(device,
106 stop_callback,
107 factory_);
108 return video_source_;
111 const blink::WebMediaStream& last_generated_stream() {
112 return last_generated_stream_;
115 const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() {
116 return last_devices_;
119 void ClearLastGeneratedStream() {
120 last_generated_stream_.reset();
123 MockMediaStreamVideoCapturerSource* last_created_video_source() const {
124 return video_source_;
127 RequestState request_state() const { return state_; }
128 content::MediaStreamRequestResult error_reason() const { return result_; }
129 blink::WebString error_name() const { return result_name_; }
131 private:
132 blink::WebMediaStream last_generated_stream_;
133 RequestState state_;
134 content::MediaStreamRequestResult result_;
135 blink::WebString result_name_;
136 blink::WebVector<blink::WebMediaDeviceInfo> last_devices_;
137 PeerConnectionDependencyFactory* factory_;
138 MockMediaStreamVideoCapturerSource* video_source_;
141 class MediaStreamImplTest : public ::testing::Test {
142 public:
143 virtual void SetUp() {
144 // Create our test object.
145 child_process_.reset(new ChildProcess());
146 dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
147 ms_dispatcher_ = new MockMediaStreamDispatcher();
148 ms_impl_.reset(new MediaStreamImplUnderTest(
149 dependency_factory_.get(),
150 scoped_ptr<MediaStreamDispatcher>(ms_dispatcher_).Pass()));
153 blink::WebMediaStream RequestLocalMediaStream() {
154 ms_impl_->RequestUserMedia();
155 FakeMediaStreamDispatcherRequestUserMediaComplete();
156 StartMockedVideoSource();
158 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
159 ms_impl_->request_state());
161 blink::WebMediaStream desc = ms_impl_->last_generated_stream();
162 content::MediaStream* native_stream =
163 content::MediaStream::GetMediaStream(desc);
164 if (!native_stream) {
165 ADD_FAILURE();
166 return desc;
169 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
170 desc.audioTracks(audio_tracks);
171 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
172 desc.videoTracks(video_tracks);
174 EXPECT_EQ(1u, audio_tracks.size());
175 EXPECT_EQ(1u, video_tracks.size());
176 EXPECT_NE(audio_tracks[0].id(), video_tracks[0].id());
177 return desc;
180 void FakeMediaStreamDispatcherRequestUserMediaComplete() {
181 // Audio request ID is used as the shared request ID.
182 ms_impl_->OnStreamGenerated(ms_dispatcher_->audio_input_request_id(),
183 ms_dispatcher_->stream_label(),
184 ms_dispatcher_->audio_input_array(),
185 ms_dispatcher_->video_array());
188 void FakeMediaStreamDispatcherRequestMediaDevicesComplete() {
189 ms_impl_->OnDevicesEnumerated(ms_dispatcher_->audio_input_request_id(),
190 ms_dispatcher_->audio_input_array());
191 ms_impl_->OnDevicesEnumerated(ms_dispatcher_->audio_output_request_id(),
192 ms_dispatcher_->audio_output_array());
193 ms_impl_->OnDevicesEnumerated(ms_dispatcher_->video_request_id(),
194 ms_dispatcher_->video_array());
197 void StartMockedVideoSource() {
198 MockMediaStreamVideoCapturerSource* video_source =
199 ms_impl_->last_created_video_source();
200 if (video_source->SourceHasAttemptedToStart())
201 video_source->StartMockedSource();
204 void FailToStartMockedVideoSource() {
205 MockMediaStreamVideoCapturerSource* video_source =
206 ms_impl_->last_created_video_source();
207 if (video_source->SourceHasAttemptedToStart())
208 video_source->FailToStartMockedSource();
211 void FailToCreateNextAudioCapturer() {
212 dependency_factory_->FailToCreateNextAudioCapturer();
215 protected:
216 base::MessageLoop message_loop_;
217 scoped_ptr<ChildProcess> child_process_;
218 MockMediaStreamDispatcher* ms_dispatcher_; // Owned my |ms_impl_|.
219 scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
220 scoped_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
223 TEST_F(MediaStreamImplTest, GenerateMediaStream) {
224 // Generate a stream with both audio and video.
225 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
228 // Test that the same source object is used if two MediaStreams are generated
229 // using the same source.
230 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithSameSource) {
231 blink::WebMediaStream desc1 = RequestLocalMediaStream();
232 blink::WebMediaStream desc2 = RequestLocalMediaStream();
234 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
235 desc1.videoTracks(desc1_video_tracks);
236 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
237 desc2.videoTracks(desc2_video_tracks);
238 EXPECT_EQ(desc1_video_tracks[0].source().id(),
239 desc2_video_tracks[0].source().id());
241 EXPECT_EQ(desc1_video_tracks[0].source().extraData(),
242 desc2_video_tracks[0].source().extraData());
244 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
245 desc1.audioTracks(desc1_audio_tracks);
246 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
247 desc2.audioTracks(desc2_audio_tracks);
248 EXPECT_EQ(desc1_audio_tracks[0].source().id(),
249 desc2_audio_tracks[0].source().id());
251 EXPECT_EQ(desc1_audio_tracks[0].source().extraData(),
252 desc2_audio_tracks[0].source().extraData());
255 // Test that the same source object is not used if two MediaStreams are
256 // generated using different sources.
257 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
258 blink::WebMediaStream desc1 = RequestLocalMediaStream();
259 // Make sure another device is selected (another |session_id|) in the next
260 // gUM request.
261 ms_dispatcher_->IncrementSessionId();
262 blink::WebMediaStream desc2 = RequestLocalMediaStream();
264 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
265 desc1.videoTracks(desc1_video_tracks);
266 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
267 desc2.videoTracks(desc2_video_tracks);
268 EXPECT_NE(desc1_video_tracks[0].source().id(),
269 desc2_video_tracks[0].source().id());
271 EXPECT_NE(desc1_video_tracks[0].source().extraData(),
272 desc2_video_tracks[0].source().extraData());
274 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
275 desc1.audioTracks(desc1_audio_tracks);
276 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
277 desc2.audioTracks(desc2_audio_tracks);
278 EXPECT_NE(desc1_audio_tracks[0].source().id(),
279 desc2_audio_tracks[0].source().id());
281 EXPECT_NE(desc1_audio_tracks[0].source().extraData(),
282 desc2_audio_tracks[0].source().extraData());
285 TEST_F(MediaStreamImplTest, StopLocalTracks) {
286 // Generate a stream with both audio and video.
287 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
289 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
290 mixed_desc.audioTracks(audio_tracks);
291 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
292 audio_track->Stop();
293 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
295 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
296 mixed_desc.videoTracks(video_tracks);
297 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
298 video_track->Stop();
299 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
302 // This test that a source is not stopped even if the tracks in a
303 // MediaStream is stopped if there are two MediaStreams with tracks using the
304 // same device. The source is stopped
305 // if there are no more MediaStream tracks using the device.
306 TEST_F(MediaStreamImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
307 // Generate a stream with both audio and video.
308 blink::WebMediaStream desc1 = RequestLocalMediaStream();
309 blink::WebMediaStream desc2 = RequestLocalMediaStream();
311 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1;
312 desc1.audioTracks(audio_tracks1);
313 MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
314 audio_track1->Stop();
315 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
317 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
318 desc2.audioTracks(audio_tracks2);
319 MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
320 audio_track2->Stop();
321 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
323 blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
324 desc1.videoTracks(video_tracks1);
325 MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
326 video_track1->Stop();
327 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
329 blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
330 desc2.videoTracks(video_tracks2);
331 MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
332 video_track2->Stop();
333 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
336 TEST_F(MediaStreamImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
337 // Generate a stream with both audio and video.
338 RequestLocalMediaStream();
339 // Makes sure the test itself don't hold a reference to the created
340 // MediaStream.
341 ms_impl_->ClearLastGeneratedStream();
343 // Expect the sources to be stopped when the MediaStream goes out of scope.
344 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
345 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
348 // Test that the MediaStreams are deleted if the owning WebFrame is closing.
349 // In the unit test the owning frame is NULL.
350 TEST_F(MediaStreamImplTest, FrameWillClose) {
351 // Test a stream with both audio and video.
352 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
353 blink::WebMediaStream desc2 = RequestLocalMediaStream();
354 ms_impl_->FrameWillClose();
355 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
356 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
359 // This test what happens if a video source to a MediaSteam fails to start.
360 TEST_F(MediaStreamImplTest, MediaVideoSourceFailToStart) {
361 ms_impl_->RequestUserMedia();
362 FakeMediaStreamDispatcherRequestUserMediaComplete();
363 FailToStartMockedVideoSource();
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 an audio source fail to initialize.
374 TEST_F(MediaStreamImplTest, MediaAudioSourceFailToInitialize) {
375 FailToCreateNextAudioCapturer();
376 ms_impl_->RequestUserMedia();
377 FakeMediaStreamDispatcherRequestUserMediaComplete();
378 StartMockedVideoSource();
379 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
380 ms_impl_->request_state());
381 EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
382 ms_impl_->error_reason());
383 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
384 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
385 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
388 // This test what happens if MediaStreamImpl is deleted before a source has
389 // started.
390 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
391 ms_impl_->RequestUserMedia();
392 FakeMediaStreamDispatcherRequestUserMediaComplete();
393 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
394 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
395 ms_impl_->request_state());
396 ms_impl_.reset();
399 // This test what happens if the WebFrame is closed while the MediaStream is
400 // being generated by the MediaStreamDispatcher.
401 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
402 ms_impl_->RequestUserMedia();
403 ms_impl_->FrameWillClose();
404 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
405 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
406 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
407 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
408 ms_impl_->request_state());
411 // This test what happens if the WebFrame is closed while the sources are being
412 // started.
413 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
414 ms_impl_->RequestUserMedia();
415 FakeMediaStreamDispatcherRequestUserMediaComplete();
416 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
417 ms_impl_->FrameWillClose();
418 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
419 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
420 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
421 ms_impl_->request_state());
424 // This test what happens if stop is called on a track after the frame has
425 // been reloaded.
426 TEST_F(MediaStreamImplTest, StopTrackAfterReload) {
427 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
428 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
429 ms_impl_->FrameWillClose();
430 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
431 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
433 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
434 mixed_desc.audioTracks(audio_tracks);
435 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
436 audio_track->Stop();
437 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
439 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
440 mixed_desc.videoTracks(video_tracks);
441 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
442 video_track->Stop();
443 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
446 TEST_F(MediaStreamImplTest, EnumerateMediaDevices) {
447 ms_impl_->RequestMediaDevices();
448 FakeMediaStreamDispatcherRequestMediaDevicesComplete();
450 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
451 ms_impl_->request_state());
453 // Audio input device with matched output ID.
454 EXPECT_FALSE(ms_impl_->last_devices()[0].deviceId().isEmpty());
455 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput,
456 ms_impl_->last_devices()[0].kind());
457 EXPECT_FALSE(ms_impl_->last_devices()[0].label().isEmpty());
458 EXPECT_FALSE(ms_impl_->last_devices()[0].groupId().isEmpty());
460 // Audio input device without matched output ID.
461 EXPECT_FALSE(ms_impl_->last_devices()[1].deviceId().isEmpty());
462 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput,
463 ms_impl_->last_devices()[1].kind());
464 EXPECT_FALSE(ms_impl_->last_devices()[1].label().isEmpty());
465 EXPECT_FALSE(ms_impl_->last_devices()[1].groupId().isEmpty());
467 // Video input device.
468 EXPECT_FALSE(ms_impl_->last_devices()[2].deviceId().isEmpty());
469 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
470 ms_impl_->last_devices()[2].kind());
471 EXPECT_FALSE(ms_impl_->last_devices()[2].label().isEmpty());
472 EXPECT_TRUE(ms_impl_->last_devices()[2].groupId().isEmpty());
474 // Audio output device.
475 EXPECT_FALSE(ms_impl_->last_devices()[3].deviceId().isEmpty());
476 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioOutput,
477 ms_impl_->last_devices()[3].kind());
478 EXPECT_FALSE(ms_impl_->last_devices()[3].label().isEmpty());
479 EXPECT_FALSE(ms_impl_->last_devices()[3].groupId().isEmpty());
481 // Verfify group IDs.
482 EXPECT_TRUE(ms_impl_->last_devices()[0].groupId().equals(
483 ms_impl_->last_devices()[3].groupId()));
484 EXPECT_FALSE(ms_impl_->last_devices()[1].groupId().equals(
485 ms_impl_->last_devices()[3].groupId()));
488 } // namespace content