• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/strings/utf_string_conversions.h"
7 #include "content/renderer/media/media_stream_extra_data.h"
8 #include "content/renderer/media/media_stream_impl.h"
9 #include "content/renderer/media/mock_media_stream_dependency_factory.h"
10 #include "content/renderer/media/mock_media_stream_dispatcher.h"
11 #include "content/renderer/media/video_capture_impl_manager.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebMediaStream.h"
14 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/platform/WebVector.h"
18 
19 namespace content {
20 
21 class MediaStreamImplUnderTest : public MediaStreamImpl {
22  public:
23   enum RequestState {
24     REQUEST_NOT_STARTED,
25     REQUEST_NOT_COMPLETE,
26     REQUEST_SUCCEEDED,
27     REQUEST_FAILED,
28   };
29 
MediaStreamImplUnderTest(MediaStreamDispatcher * media_stream_dispatcher,MediaStreamDependencyFactory * dependency_factory)30   MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
31                            MediaStreamDependencyFactory* dependency_factory)
32       : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
33         state_(REQUEST_NOT_STARTED) {
34   }
35 
RequestUserMedia()36   void RequestUserMedia() {
37     blink::WebUserMediaRequest user_media_request;
38     state_ = REQUEST_NOT_COMPLETE;
39     requestUserMedia(user_media_request);
40   }
41 
CompleteGetUserMediaRequest(const blink::WebMediaStream & stream,blink::WebUserMediaRequest * request_info,bool request_succeeded)42   virtual void CompleteGetUserMediaRequest(
43       const blink::WebMediaStream& stream,
44       blink::WebUserMediaRequest* request_info,
45       bool request_succeeded) OVERRIDE {
46     last_generated_stream_ = stream;
47     state_ = request_succeeded ? REQUEST_SUCCEEDED : REQUEST_FAILED;
48   }
49 
GetMediaStream(const GURL & url)50   virtual blink::WebMediaStream GetMediaStream(
51       const GURL& url) OVERRIDE {
52     return last_generated_stream_;
53   }
54 
55   using MediaStreamImpl::OnLocalMediaStreamStop;
56   using MediaStreamImpl::OnLocalSourceStop;
57 
last_generated_stream()58   const blink::WebMediaStream& last_generated_stream() {
59     return last_generated_stream_;
60   }
61 
request_state() const62   RequestState request_state() const { return state_; }
63 
64  private:
65   blink::WebMediaStream last_generated_stream_;
66   RequestState state_;
67 };
68 
69 class MediaStreamImplTest : public ::testing::Test {
70  public:
SetUp()71   virtual void SetUp() {
72     // Create our test object.
73     ms_dispatcher_.reset(new MockMediaStreamDispatcher());
74     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
75     ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
76                                                 dependency_factory_.get()));
77   }
78 
RequestLocalMediaStream()79   blink::WebMediaStream RequestLocalMediaStream() {
80     ms_impl_->RequestUserMedia();
81     FakeMediaStreamDispatcherComplete();
82     ChangeVideoSourceStateToLive();
83     ChangeAudioSourceStateToLive();
84 
85     EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
86               ms_impl_->request_state());
87 
88     blink::WebMediaStream desc = ms_impl_->last_generated_stream();
89     content::MediaStreamExtraData* extra_data =
90         static_cast<content::MediaStreamExtraData*>(desc.extraData());
91     if (!extra_data || !extra_data->stream().get()) {
92       ADD_FAILURE();
93       return desc;
94     }
95 
96     EXPECT_EQ(1u, extra_data->stream()->GetAudioTracks().size());
97     EXPECT_EQ(1u, extra_data->stream()->GetVideoTracks().size());
98     EXPECT_NE(extra_data->stream()->GetAudioTracks()[0]->id(),
99               extra_data->stream()->GetVideoTracks()[0]->id());
100     return desc;
101   }
102 
FakeMediaStreamDispatcherComplete()103   void FakeMediaStreamDispatcherComplete() {
104     ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(),
105                                 ms_dispatcher_->stream_label(),
106                                 ms_dispatcher_->audio_array(),
107                                 ms_dispatcher_->video_array());
108   }
109 
ChangeVideoSourceStateToLive()110   void ChangeVideoSourceStateToLive() {
111     if (dependency_factory_->last_video_source() != NULL) {
112       dependency_factory_->last_video_source()->SetLive();
113     }
114   }
115 
ChangeAudioSourceStateToLive()116   void ChangeAudioSourceStateToLive() {
117     if (dependency_factory_->last_audio_source() != NULL) {
118       dependency_factory_->last_audio_source()->SetLive();
119     }
120   }
121 
ChangeVideoSourceStateToEnded()122   void ChangeVideoSourceStateToEnded() {
123     if (dependency_factory_->last_video_source() != NULL) {
124       dependency_factory_->last_video_source()->SetEnded();
125     }
126   }
127 
ChangeAudioSourceStateToEnded()128   void ChangeAudioSourceStateToEnded() {
129     if (dependency_factory_->last_audio_source() != NULL) {
130       dependency_factory_->last_audio_source()->SetEnded();
131     }
132   }
133 
134  protected:
135   scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
136   scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
137   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
138 };
139 
TEST_F(MediaStreamImplTest,GenerateMediaStream)140 TEST_F(MediaStreamImplTest, GenerateMediaStream) {
141   // Generate a stream with both audio and video.
142   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
143 }
144 
145 // Test that the same source object is used if two MediaStreams are generated
146 // using the same source.
TEST_F(MediaStreamImplTest,GenerateTwoMediaStreamsWithSameSource)147 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithSameSource) {
148   blink::WebMediaStream desc1 = RequestLocalMediaStream();
149   blink::WebMediaStream desc2 = RequestLocalMediaStream();
150 
151   blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
152   desc1.videoTracks(desc1_video_tracks);
153   blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
154   desc2.videoTracks(desc2_video_tracks);
155   EXPECT_EQ(desc1_video_tracks[0].source().id(),
156             desc2_video_tracks[0].source().id());
157 
158   EXPECT_EQ(desc1_video_tracks[0].source().extraData(),
159             desc2_video_tracks[0].source().extraData());
160 
161   blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
162   desc1.audioTracks(desc1_audio_tracks);
163   blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
164   desc2.audioTracks(desc2_audio_tracks);
165   EXPECT_EQ(desc1_audio_tracks[0].source().id(),
166             desc2_audio_tracks[0].source().id());
167 
168   EXPECT_EQ(desc1_audio_tracks[0].source().extraData(),
169             desc2_audio_tracks[0].source().extraData());
170 }
171 
172 // Test that the same source object is not used if two MediaStreams are
173 // generated using different sources.
TEST_F(MediaStreamImplTest,GenerateTwoMediaStreamsWithDifferentSources)174 TEST_F(MediaStreamImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
175   blink::WebMediaStream desc1 = RequestLocalMediaStream();
176   // Make sure another device is selected (another |session_id|) in  the next
177   // gUM request.
178   ms_dispatcher_->IncrementSessionId();
179   blink::WebMediaStream desc2 = RequestLocalMediaStream();
180 
181   blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
182   desc1.videoTracks(desc1_video_tracks);
183   blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
184   desc2.videoTracks(desc2_video_tracks);
185   EXPECT_NE(desc1_video_tracks[0].source().id(),
186             desc2_video_tracks[0].source().id());
187 
188   EXPECT_NE(desc1_video_tracks[0].source().extraData(),
189             desc2_video_tracks[0].source().extraData());
190 
191   blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
192   desc1.audioTracks(desc1_audio_tracks);
193   blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
194   desc2.audioTracks(desc2_audio_tracks);
195   EXPECT_NE(desc1_audio_tracks[0].source().id(),
196             desc2_audio_tracks[0].source().id());
197 
198   EXPECT_NE(desc1_audio_tracks[0].source().extraData(),
199             desc2_audio_tracks[0].source().extraData());
200 }
201 
TEST_F(MediaStreamImplTest,StopLocalMediaStream)202 TEST_F(MediaStreamImplTest, StopLocalMediaStream) {
203   // Generate a stream with both audio and video.
204   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
205 
206   // Stop generated local streams.
207   ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8());
208   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
209   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
210 }
211 
212 // This test that a source is not stopped even if the MediaStream is stopped if
213 // there are two MediaStreams using the same device. The source is stopped
214 // if there are no more MediaStreams using the device.
TEST_F(MediaStreamImplTest,StopLocalMediaStreamWhenTwoStreamUseSameDevices)215 TEST_F(MediaStreamImplTest, StopLocalMediaStreamWhenTwoStreamUseSameDevices) {
216   // Generate a stream with both audio and video.
217   blink::WebMediaStream desc1 = RequestLocalMediaStream();
218   blink::WebMediaStream desc2 = RequestLocalMediaStream();
219 
220   ms_impl_->OnLocalMediaStreamStop(desc2.id().utf8());
221   EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
222   EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
223 
224   ms_impl_->OnLocalMediaStreamStop(desc1.id().utf8());
225   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
226   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
227 }
228 
229 // Test that the source is stopped even if there are two MediaStreams using
230 // the same source.
TEST_F(MediaStreamImplTest,StopSource)231 TEST_F(MediaStreamImplTest, StopSource) {
232   // Generate a stream with both audio and video.
233   blink::WebMediaStream desc1 = RequestLocalMediaStream();
234   blink::WebMediaStream desc2 = RequestLocalMediaStream();
235 
236   // Stop the video source.
237   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
238   desc1.videoTracks(video_tracks);
239   ms_impl_->OnLocalSourceStop(video_tracks[0].source());
240   EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
241   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
242 
243   // Stop the audio source.
244   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
245   desc1.audioTracks(audio_tracks);
246   ms_impl_->OnLocalSourceStop(audio_tracks[0].source());
247   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
248   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
249 }
250 
251 // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
252 // In the unit test the owning frame is NULL.
TEST_F(MediaStreamImplTest,FrameWillClose)253 TEST_F(MediaStreamImplTest, FrameWillClose) {
254   // Test a stream with both audio and video.
255   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
256 
257   // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
258   // In the unit test the owning frame is NULL.
259   ms_impl_->FrameWillClose(NULL);
260   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
261   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
262 }
263 
264 // This test what happens if a source to a MediaSteam fails to start.
TEST_F(MediaStreamImplTest,MediaSourceFailToStart)265 TEST_F(MediaStreamImplTest, MediaSourceFailToStart) {
266   ms_impl_->RequestUserMedia();
267   FakeMediaStreamDispatcherComplete();
268   ChangeVideoSourceStateToEnded();
269   ChangeAudioSourceStateToEnded();
270   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
271             ms_impl_->request_state());
272   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
273   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
274   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
275 }
276 
277 // This test what happens if MediaStreamImpl is deleted while the sources of a
278 // MediaStream is being started.
TEST_F(MediaStreamImplTest,MediaStreamImplShutDown)279 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
280   ms_impl_->RequestUserMedia();
281   FakeMediaStreamDispatcherComplete();
282   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
283   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
284             ms_impl_->request_state());
285   ms_impl_.reset();
286   ChangeAudioSourceStateToLive();
287   ChangeVideoSourceStateToLive();
288 }
289 
290 // This test what happens if the WebFrame is closed while the MediaStream is
291 // being generated by the MediaStreamDispatcher.
TEST_F(MediaStreamImplTest,ReloadFrameWhileGeneratingStream)292 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
293   ms_impl_->RequestUserMedia();
294   ms_impl_->FrameWillClose(NULL);
295   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
296   EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
297   EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
298   ChangeAudioSourceStateToLive();
299   ChangeVideoSourceStateToLive();
300   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
301             ms_impl_->request_state());
302 }
303 
304 // This test what happens if the WebFrame is closed while the sources are being
305 // started by MediaStreamDependencyFactory.
TEST_F(MediaStreamImplTest,ReloadFrameWhileGeneratingSources)306 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
307   ms_impl_->RequestUserMedia();
308   FakeMediaStreamDispatcherComplete();
309   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
310   ms_impl_->FrameWillClose(NULL);
311   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
312   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
313   ChangeAudioSourceStateToLive();
314   ChangeVideoSourceStateToLive();
315   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
316             ms_impl_->request_state());
317 }
318 
319 // This test what happens if stop is called on a stream after the frame has
320 // been reloaded.
TEST_F(MediaStreamImplTest,StopStreamAfterReload)321 TEST_F(MediaStreamImplTest, StopStreamAfterReload) {
322   blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
323   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
324   ms_impl_->FrameWillClose(NULL);
325   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
326   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
327   ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8());
328   EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
329   EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
330 }
331 
332 }  // namespace content
333