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 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 36 void RequestUserMedia() { 37 WebKit::WebUserMediaRequest user_media_request; 38 state_ = REQUEST_NOT_COMPLETE; 39 requestUserMedia(user_media_request); 40 } 41 42 virtual void CompleteGetUserMediaRequest( 43 const WebKit::WebMediaStream& stream, 44 WebKit::WebUserMediaRequest* request_info, 45 bool request_succeeded) OVERRIDE { 46 last_generated_stream_ = stream; 47 state_ = request_succeeded ? REQUEST_SUCCEEDED : REQUEST_FAILED; 48 } 49 50 virtual WebKit::WebMediaStream GetMediaStream( 51 const GURL& url) OVERRIDE { 52 return last_generated_stream_; 53 } 54 55 using MediaStreamImpl::OnLocalMediaStreamStop; 56 57 const WebKit::WebMediaStream& last_generated_stream() { 58 return last_generated_stream_; 59 } 60 61 RequestState request_state() const { return state_; } 62 63 private: 64 WebKit::WebMediaStream last_generated_stream_; 65 RequestState state_; 66 }; 67 68 class MediaStreamImplTest : public ::testing::Test { 69 public: 70 virtual void SetUp() { 71 // Create our test object. 72 ms_dispatcher_.reset(new MockMediaStreamDispatcher()); 73 dependency_factory_.reset(new MockMediaStreamDependencyFactory()); 74 ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(), 75 dependency_factory_.get())); 76 } 77 78 WebKit::WebMediaStream RequestLocalMediaStream() { 79 ms_impl_->RequestUserMedia(); 80 FakeMediaStreamDispatcherComplete(); 81 ChangeVideoSourceStateToLive(); 82 ChangeAudioSourceStateToLive(); 83 84 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED, 85 ms_impl_->request_state()); 86 87 WebKit::WebMediaStream desc = ms_impl_->last_generated_stream(); 88 content::MediaStreamExtraData* extra_data = 89 static_cast<content::MediaStreamExtraData*>(desc.extraData()); 90 if (!extra_data || !extra_data->stream().get()) { 91 ADD_FAILURE(); 92 return desc; 93 } 94 95 EXPECT_EQ(1u, extra_data->stream()->GetAudioTracks().size()); 96 EXPECT_EQ(1u, extra_data->stream()->GetVideoTracks().size()); 97 EXPECT_NE(extra_data->stream()->GetAudioTracks()[0]->id(), 98 extra_data->stream()->GetVideoTracks()[0]->id()); 99 return desc; 100 } 101 102 void FakeMediaStreamDispatcherComplete() { 103 ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(), 104 ms_dispatcher_->stream_label(), 105 ms_dispatcher_->audio_array(), 106 ms_dispatcher_->video_array()); 107 } 108 109 void ChangeVideoSourceStateToLive() { 110 if (dependency_factory_->last_video_source() != NULL) { 111 dependency_factory_->last_video_source()->SetLive(); 112 } 113 } 114 115 void ChangeAudioSourceStateToLive() { 116 if (dependency_factory_->last_audio_source() != NULL) { 117 dependency_factory_->last_audio_source()->SetLive(); 118 } 119 } 120 121 void ChangeVideoSourceStateToEnded() { 122 if (dependency_factory_->last_video_source() != NULL) { 123 dependency_factory_->last_video_source()->SetEnded(); 124 } 125 } 126 127 void ChangeAudioSourceStateToEnded() { 128 if (dependency_factory_->last_audio_source() != NULL) { 129 dependency_factory_->last_audio_source()->SetEnded(); 130 } 131 } 132 133 protected: 134 scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_; 135 scoped_ptr<MediaStreamImplUnderTest> ms_impl_; 136 scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_; 137 }; 138 139 TEST_F(MediaStreamImplTest, LocalMediaStream) { 140 // Test a stream with both audio and video. 141 WebKit::WebMediaStream mixed_desc = RequestLocalMediaStream(); 142 143 // Test a stream with audio only. 144 WebKit::WebMediaStream audio_desc = RequestLocalMediaStream(); 145 146 // Test a stream with video only. 147 WebKit::WebMediaStream video_desc = RequestLocalMediaStream(); 148 149 // Stop generated local streams. 150 ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8()); 151 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); 152 ms_impl_->OnLocalMediaStreamStop(audio_desc.id().utf8()); 153 EXPECT_EQ(2, ms_dispatcher_->stop_stream_counter()); 154 155 // Test that the MediaStreams are deleted if the owning WebFrame is deleted. 156 // In the unit test the owning frame is NULL. 157 ms_impl_->FrameWillClose(NULL); 158 EXPECT_EQ(3, ms_dispatcher_->stop_stream_counter()); 159 } 160 161 // This test what happens if a source to a MediaSteam fails to start. 162 TEST_F(MediaStreamImplTest, MediaSourceFailToStart) { 163 ms_impl_->RequestUserMedia(); 164 FakeMediaStreamDispatcherComplete(); 165 ChangeVideoSourceStateToEnded(); 166 ChangeAudioSourceStateToEnded(); 167 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED, 168 ms_impl_->request_state()); 169 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 170 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); 171 } 172 173 // This test what happens if MediaStreamImpl is deleted while the sources of a 174 // MediaStream is being started. 175 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) { 176 ms_impl_->RequestUserMedia(); 177 FakeMediaStreamDispatcherComplete(); 178 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 179 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE, 180 ms_impl_->request_state()); 181 ms_impl_.reset(); 182 ChangeAudioSourceStateToLive(); 183 ChangeVideoSourceStateToLive(); 184 } 185 186 // This test what happens if the WebFrame is closed while the MediaStream is 187 // being generated by the MediaStreamDispatcher. 188 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) { 189 ms_impl_->RequestUserMedia(); 190 ms_impl_->FrameWillClose(NULL); 191 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 192 EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter()); 193 ChangeAudioSourceStateToLive(); 194 ChangeVideoSourceStateToLive(); 195 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE, 196 ms_impl_->request_state()); 197 } 198 199 // This test what happens if the WebFrame is closed while the sources are being 200 // started by MediaStreamDependencyFactory. 201 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) { 202 ms_impl_->RequestUserMedia(); 203 FakeMediaStreamDispatcherComplete(); 204 EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter()); 205 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 206 ms_impl_->FrameWillClose(NULL); 207 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); 208 ChangeAudioSourceStateToLive(); 209 ChangeVideoSourceStateToLive(); 210 EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE, 211 ms_impl_->request_state()); 212 } 213 214 // This test what happens if stop is called on a stream after the frame has 215 // been reloaded. 216 TEST_F(MediaStreamImplTest, StopStreamAfterReload) { 217 WebKit::WebMediaStream mixed_desc = RequestLocalMediaStream(); 218 EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter()); 219 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 220 ms_impl_->FrameWillClose(NULL); 221 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); 222 ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8()); 223 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); 224 } 225 226 } // namespace content 227