Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / media_stream_impl_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 "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_dependency_factory.h"
13 #include "content/renderer/media/mock_media_stream_dispatcher.h"
14 #include "content/renderer/media/mock_media_stream_video_source.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebMediaStream.h"
17 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
18 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
19 #include "third_party/WebKit/public/platform/WebString.h"
20 #include "third_party/WebKit/public/platform/WebVector.h"
21
22 namespace content {
23
24 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource {
25  public:
26   MockMediaStreamVideoCapturerSource(
27       const StreamDeviceInfo& device,
28       const SourceStoppedCallback& stop_callback,
29       MediaStreamDependencyFactory* factory)
30   : MockMediaStreamVideoSource(false) {
31     SetDeviceInfo(device);
32     SetStopCallback(stop_callback);
33   }
34 };
35
36 class MediaStreamImplUnderTest : public MediaStreamImpl {
37  public:
38   enum RequestState {
39     REQUEST_NOT_STARTED,
40     REQUEST_NOT_COMPLETE,
41     REQUEST_SUCCEEDED,
42     REQUEST_FAILED,
43   };
44
45   MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
46                            MediaStreamDependencyFactory* dependency_factory)
47       : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
48         state_(REQUEST_NOT_STARTED),
49         result_(NUM_MEDIA_REQUEST_RESULTS),
50         factory_(dependency_factory),
51         video_source_(NULL) {
52   }
53
54   void RequestUserMedia() {
55     blink::WebUserMediaRequest user_media_request;
56     state_ = REQUEST_NOT_COMPLETE;
57     requestUserMedia(user_media_request);
58   }
59
60   virtual void GetUserMediaRequestSucceeded(
61       const blink::WebMediaStream& stream,
62       blink::WebUserMediaRequest* request_info) OVERRIDE {
63     last_generated_stream_ = stream;
64     state_ = REQUEST_SUCCEEDED;
65   }
66
67   virtual void GetUserMediaRequestFailed(
68       blink::WebUserMediaRequest* request_info,
69       content::MediaStreamRequestResult result) OVERRIDE {
70     last_generated_stream_.reset();
71     state_ = REQUEST_FAILED;
72     result_ = result;
73   }
74
75   virtual MediaStreamVideoSource* CreateVideoSource(
76       const StreamDeviceInfo& device,
77       const MediaStreamSource::SourceStoppedCallback& stop_callback) OVERRIDE {
78     video_source_ = new MockMediaStreamVideoCapturerSource(device,
79                                                            stop_callback,
80                                                            factory_);
81     return video_source_;
82   }
83
84   const blink::WebMediaStream& last_generated_stream() {
85     return last_generated_stream_;
86   }
87
88   void ClearLastGeneratedStream() {
89     last_generated_stream_.reset();
90   }
91
92   MockMediaStreamVideoCapturerSource* last_created_video_source() const {
93     return video_source_;
94   }
95
96   RequestState request_state() const { return state_; }
97   content::MediaStreamRequestResult error_reason() const { return result_; }
98
99  private:
100   blink::WebMediaStream last_generated_stream_;
101   RequestState state_;
102   content::MediaStreamRequestResult result_;
103   MediaStreamDependencyFactory* factory_;
104   MockMediaStreamVideoCapturerSource* video_source_;
105 };
106
107 class MediaStreamImplTest : public ::testing::Test {
108  public:
109   virtual void SetUp() {
110     // Create our test object.
111     child_process_.reset(new ChildProcess());
112     ms_dispatcher_.reset(new MockMediaStreamDispatcher());
113     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
114     ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
115                                                 dependency_factory_.get()));
116   }
117
118   blink::WebMediaStream RequestLocalMediaStream() {
119     ms_impl_->RequestUserMedia();
120     FakeMediaStreamDispatcherComplete();
121     StartMockedVideoSource();
122
123     EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
124               ms_impl_->request_state());
125
126     blink::WebMediaStream desc = ms_impl_->last_generated_stream();
127     content::MediaStream* native_stream =
128         content::MediaStream::GetMediaStream(desc);
129     if (!native_stream) {
130       ADD_FAILURE();
131       return desc;
132     }
133
134     blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
135     desc.audioTracks(audio_tracks);
136     blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
137     desc.videoTracks(video_tracks);
138
139     EXPECT_EQ(1u, audio_tracks.size());
140     EXPECT_EQ(1u, video_tracks.size());
141     EXPECT_NE(audio_tracks[0].id(), video_tracks[0].id());
142     return desc;
143   }
144
145   void FakeMediaStreamDispatcherComplete() {
146     ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(),
147                                 ms_dispatcher_->stream_label(),
148                                 ms_dispatcher_->audio_array(),
149                                 ms_dispatcher_->video_array());
150   }
151
152   void StartMockedVideoSource() {
153     MockMediaStreamVideoCapturerSource* video_source =
154         ms_impl_->last_created_video_source();
155     if (video_source->SourceHasAttemptedToStart())
156       video_source->StartMockedSource();
157   }
158
159   void FailToStartMockedVideoSource() {
160     MockMediaStreamVideoCapturerSource* video_source =
161         ms_impl_->last_created_video_source();
162     if (video_source->SourceHasAttemptedToStart())
163       video_source->FailToStartMockedSource();
164   }
165
166   void FailToCreateNextAudioCapturer() {
167     dependency_factory_->FailToCreateNextAudioCapturer();
168   }
169
170  protected:
171   base::MessageLoop message_loop_;
172   scoped_ptr<ChildProcess> child_process_;
173   scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
174   scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
175   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
176 };
177
178 TEST_F(MediaStreamImplTest, GenerateMediaStream) {
179   // Generate a stream with both audio and video.
180   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
181 }
182
183 // Test that the same source object is used if two MediaStreams are generated
184 // using the same source.
185 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithSameSource) {
186   blink::WebMediaStream desc1 = RequestLocalMediaStream();
187   blink::WebMediaStream desc2 = RequestLocalMediaStream();
188
189   blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
190   desc1.videoTracks(desc1_video_tracks);
191   blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
192   desc2.videoTracks(desc2_video_tracks);
193   EXPECT_EQ(desc1_video_tracks[0].source().id(),
194             desc2_video_tracks[0].source().id());
195
196   EXPECT_EQ(desc1_video_tracks[0].source().extraData(),
197             desc2_video_tracks[0].source().extraData());
198
199   blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
200   desc1.audioTracks(desc1_audio_tracks);
201   blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
202   desc2.audioTracks(desc2_audio_tracks);
203   EXPECT_EQ(desc1_audio_tracks[0].source().id(),
204             desc2_audio_tracks[0].source().id());
205
206   EXPECT_EQ(desc1_audio_tracks[0].source().extraData(),
207             desc2_audio_tracks[0].source().extraData());
208 }
209
210 // Test that the same source object is not used if two MediaStreams are
211 // generated using different sources.
212 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
213   blink::WebMediaStream desc1 = RequestLocalMediaStream();
214   // Make sure another device is selected (another |session_id|) in  the next
215   // gUM request.
216   ms_dispatcher_->IncrementSessionId();
217   blink::WebMediaStream desc2 = RequestLocalMediaStream();
218
219   blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
220   desc1.videoTracks(desc1_video_tracks);
221   blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
222   desc2.videoTracks(desc2_video_tracks);
223   EXPECT_NE(desc1_video_tracks[0].source().id(),
224             desc2_video_tracks[0].source().id());
225
226   EXPECT_NE(desc1_video_tracks[0].source().extraData(),
227             desc2_video_tracks[0].source().extraData());
228
229   blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
230   desc1.audioTracks(desc1_audio_tracks);
231   blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
232   desc2.audioTracks(desc2_audio_tracks);
233   EXPECT_NE(desc1_audio_tracks[0].source().id(),
234             desc2_audio_tracks[0].source().id());
235
236   EXPECT_NE(desc1_audio_tracks[0].source().extraData(),
237             desc2_audio_tracks[0].source().extraData());
238 }
239
240 TEST_F(MediaStreamImplTest, StopLocalTracks) {
241   // Generate a stream with both audio and video.
242   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
243
244   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
245   mixed_desc.audioTracks(audio_tracks);
246   MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
247   audio_track->Stop();
248   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
249
250   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
251   mixed_desc.videoTracks(video_tracks);
252   MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
253   video_track->Stop();
254   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
255 }
256
257 // This test that a source is not stopped even if the tracks in a
258 // MediaStream is stopped if there are two MediaStreams with tracks using the
259 // same device. The source is stopped
260 // if there are no more MediaStream tracks using the device.
261 TEST_F(MediaStreamImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
262   // Generate a stream with both audio and video.
263   blink::WebMediaStream desc1 = RequestLocalMediaStream();
264   blink::WebMediaStream desc2 = RequestLocalMediaStream();
265
266   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1;
267   desc1.audioTracks(audio_tracks1);
268   MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
269   audio_track1->Stop();
270   EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
271
272   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
273   desc2.audioTracks(audio_tracks2);
274   MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
275   audio_track2->Stop();
276   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
277
278   blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
279   desc1.videoTracks(video_tracks1);
280   MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
281   video_track1->Stop();
282   EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
283
284   blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
285   desc2.videoTracks(video_tracks2);
286   MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
287   video_track2->Stop();
288   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
289 }
290
291 TEST_F(MediaStreamImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
292   // Generate a stream with both audio and video.
293   RequestLocalMediaStream();
294   // Makes sure the test itself don't hold a reference to the created
295   // MediaStream.
296   ms_impl_->ClearLastGeneratedStream();
297
298   // Expect the sources to be stopped when the MediaStream goes out of scope.
299   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
300   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
301 }
302
303 // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
304 // In the unit test the owning frame is NULL.
305 TEST_F(MediaStreamImplTest, FrameWillClose) {
306   // Test a stream with both audio and video.
307   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
308   blink::WebMediaStream desc2 = RequestLocalMediaStream();
309
310   // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
311   // In the unit test the owning frame is NULL.
312   ms_impl_->FrameWillClose(NULL);
313   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
314   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
315 }
316
317 // This test what happens if a video source to a MediaSteam fails to start.
318 TEST_F(MediaStreamImplTest, MediaVideoSourceFailToStart) {
319   ms_impl_->RequestUserMedia();
320   FakeMediaStreamDispatcherComplete();
321   FailToStartMockedVideoSource();
322   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
323             ms_impl_->request_state());
324   EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
325             ms_impl_->error_reason());
326   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
327   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
328   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
329 }
330
331 // This test what happens if an audio source fail to initialize.
332 TEST_F(MediaStreamImplTest, MediaAudioSourceFailToInitialize) {
333   FailToCreateNextAudioCapturer();
334   ms_impl_->RequestUserMedia();
335   FakeMediaStreamDispatcherComplete();
336   StartMockedVideoSource();
337   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
338             ms_impl_->request_state());
339   EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
340             ms_impl_->error_reason());
341   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
342   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
343   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
344 }
345
346 // This test what happens if MediaStreamImpl is deleted before a source has
347 // started.
348 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
349   ms_impl_->RequestUserMedia();
350   FakeMediaStreamDispatcherComplete();
351   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
352   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
353             ms_impl_->request_state());
354   ms_impl_.reset();
355 }
356
357 // This test what happens if the WebFrame is closed while the MediaStream is
358 // being generated by the MediaStreamDispatcher.
359 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
360   ms_impl_->RequestUserMedia();
361   ms_impl_->FrameWillClose(NULL);
362   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
363   EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
364   EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
365   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
366             ms_impl_->request_state());
367 }
368
369 // This test what happens if the WebFrame is closed while the sources are being
370 // started.
371 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
372   ms_impl_->RequestUserMedia();
373   FakeMediaStreamDispatcherComplete();
374   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
375   ms_impl_->FrameWillClose(NULL);
376   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
377   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
378   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
379             ms_impl_->request_state());
380 }
381
382 // This test what happens if stop is called on a track after the frame has
383 // been reloaded.
384 TEST_F(MediaStreamImplTest, StopTrackAfterReload) {
385   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
386   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
387   ms_impl_->FrameWillClose(NULL);
388   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
389   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
390
391   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
392   mixed_desc.audioTracks(audio_tracks);
393   MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
394   audio_track->Stop();
395   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
396
397   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
398   mixed_desc.videoTracks(video_tracks);
399   MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
400   video_track->Stop();
401   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
402 }
403
404 }  // namespace content