| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
| 8 #include "content/renderer/media/media_stream_extra_data.h" |
| 8 #include "content/renderer/media/media_stream_impl.h" | 9 #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_dependency_factory.h" |
| 10 #include "content/renderer/media/mock_media_stream_dispatcher.h" | 11 #include "content/renderer/media/mock_media_stream_dispatcher.h" |
| 11 #include "content/renderer/media/mock_web_peer_connection_00_handler_client.h" | 12 #include "content/renderer/media/mock_web_peer_connection_00_handler_client.h" |
| 12 #include "content/renderer/media/mock_web_peer_connection_handler_client.h" | 13 #include "content/renderer/media/mock_web_peer_connection_handler_client.h" |
| 13 #include "content/renderer/media/peer_connection_handler.h" | 14 #include "content/renderer/media/peer_connection_handler.h" |
| 14 #include "content/renderer/media/peer_connection_handler_jsep.h" | 15 #include "content/renderer/media/peer_connection_handler_jsep.h" |
| 15 #include "content/renderer/media/video_capture_impl_manager.h" | 16 #include "content/renderer/media/video_capture_impl_manager.h" |
| 16 #include "content/renderer/p2p/socket_dispatcher.h" | 17 #include "content/renderer/p2p/socket_dispatcher.h" |
| 17 #include "media/base/message_loop_factory.h" | 18 #include "media/base/message_loop_factory.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre
amSource.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre
amSource.h" |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConne
ction00Handler.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConne
ction00Handler.h" |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConne
ctionHandler.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConne
ctionHandler.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
| 23 | 24 |
| 24 // TODO(perkj): Currently a media stream is identified by its sources. | 25 class MediaStreamImplUnderTest : public MediaStreamImpl { |
| 25 // This is currently being changed in WebKit. | 26 public: |
| 26 // Remove the creation of WebKitSourceVectors when that has landed. | 27 MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher, |
| 27 static std::string CreateTrackLabel( | 28 content::P2PSocketDispatcher* p2p_socket_dispatcher, |
| 28 const std::string& manager_label, | 29 VideoCaptureImplManager* vc_manager, |
| 29 int session_id, | 30 MediaStreamDependencyFactory* dependency_factory) |
| 30 bool is_video) { | 31 : MediaStreamImpl(NULL, media_stream_dispatcher, p2p_socket_dispatcher, |
| 31 std::string track_label = manager_label; | 32 vc_manager, dependency_factory) { |
| 32 if (is_video) { | |
| 33 track_label += "#video-"; | |
| 34 } else { | |
| 35 track_label += "#audio-"; | |
| 36 } | 33 } |
| 37 track_label += session_id; | 34 virtual void CompleteGetUserMediaRequest( |
| 38 return track_label; | 35 const WebKit::WebMediaStreamDescriptor& stream, |
| 39 } | 36 WebKit::WebUserMediaRequest* request) { |
| 37 last_generated_stream_ = stream; |
| 38 } |
| 40 | 39 |
| 41 // TODO(perkj): Currently a media stream is identified by its sources. | 40 virtual WebKit::WebMediaStreamDescriptor GetMediaStream( |
| 42 // This is currently being changed in WebKit. | 41 const GURL& url) { |
| 43 // Remove the creation of WebKitSourceVectors when that has landed. | 42 return last_generated_stream_; |
| 44 static void CreateWebKitSourceVector( | 43 } |
| 45 const std::string& label, | |
| 46 const media_stream::StreamDeviceInfoArray& devices, | |
| 47 WebKit::WebMediaStreamSource::Type type, | |
| 48 WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { | |
| 49 ASSERT(devices.size() == webkit_sources.size()); | |
| 50 | 44 |
| 51 for (size_t i = 0; i < devices.size(); ++i) { | 45 const WebKit::WebMediaStreamDescriptor& last_generated_stream() { |
| 52 std::string track_label = CreateTrackLabel( | 46 return last_generated_stream_; |
| 53 label, devices[i].session_id, | |
| 54 type == WebKit::WebMediaStreamSource::TypeVideo); | |
| 55 webkit_sources[i].initialize( | |
| 56 UTF8ToUTF16(track_label), | |
| 57 type, | |
| 58 UTF8ToUTF16(devices[i].name)); | |
| 59 } | 47 } |
| 60 } | 48 |
| 49 private: |
| 50 WebKit::WebMediaStreamDescriptor last_generated_stream_; |
| 51 }; |
| 61 | 52 |
| 62 class MediaStreamImplTest : public ::testing::Test { | 53 class MediaStreamImplTest : public ::testing::Test { |
| 63 public: | 54 public: |
| 64 void SetUp() { | 55 void SetUp() { |
| 65 // Create our test object. | 56 // Create our test object. |
| 66 ms_dispatcher_.reset(new MockMediaStreamDispatcher()); | 57 ms_dispatcher_.reset(new MockMediaStreamDispatcher()); |
| 67 p2p_socket_dispatcher_.reset(new content::P2PSocketDispatcher(NULL)); | 58 p2p_socket_dispatcher_.reset(new content::P2PSocketDispatcher(NULL)); |
| 68 scoped_refptr<VideoCaptureImplManager> vc_manager( | 59 scoped_refptr<VideoCaptureImplManager> vc_manager( |
| 69 new VideoCaptureImplManager()); | 60 new VideoCaptureImplManager()); |
| 70 MockMediaStreamDependencyFactory* dependency_factory = | 61 MockMediaStreamDependencyFactory* dependency_factory = |
| 71 new MockMediaStreamDependencyFactory(vc_manager); | 62 new MockMediaStreamDependencyFactory(vc_manager); |
| 72 ms_impl_.reset(new MediaStreamImpl(NULL, | 63 ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(), |
| 73 ms_dispatcher_.get(), | 64 p2p_socket_dispatcher_.get(), |
| 74 p2p_socket_dispatcher_.get(), | 65 vc_manager.get(), |
| 75 vc_manager.get(), | 66 dependency_factory)); |
| 76 dependency_factory)); | |
| 77 } | 67 } |
| 78 | 68 |
| 79 void TearDown() { | 69 void TearDown() { |
| 80 // Make sure the message created by | 70 // Make sure the message created by |
| 81 // P2PSocketDispatcher::AsyncMessageSender::Send is handled before | 71 // P2PSocketDispatcher::AsyncMessageSender::Send is handled before |
| 82 // tear down to avoid a memory leak. | 72 // tear down to avoid a memory leak. |
| 83 loop_.RunAllPending(); | 73 loop_.RunAllPending(); |
| 84 } | 74 } |
| 85 | 75 |
| 86 WebKit::WebMediaStreamDescriptor RequestLocalMediaStream(bool audio, | 76 WebKit::WebMediaStreamDescriptor RequestLocalMediaStream(bool audio, |
| 87 bool video) { | 77 bool video) { |
| 88 WebKit::WebUserMediaRequest user_media_request; | 78 WebKit::WebUserMediaRequest user_media_request; |
| 89 WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources( | 79 WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources( |
| 90 audio ? static_cast<size_t>(1) : 0); | 80 audio ? static_cast<size_t>(1) : 0); |
| 91 WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources( | 81 WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources( |
| 92 video ? static_cast<size_t>(1) : 0); | 82 video ? static_cast<size_t>(1) : 0); |
| 93 ms_impl_->requestUserMedia(user_media_request, audio_sources, | 83 ms_impl_->requestUserMedia(user_media_request, audio_sources, |
| 94 video_sources); | 84 video_sources); |
| 95 | 85 |
| 96 ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(), | 86 ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(), |
| 97 ms_dispatcher_->stream_label(), | 87 ms_dispatcher_->stream_label(), |
| 98 ms_dispatcher_->audio_array(), | 88 ms_dispatcher_->audio_array(), |
| 99 ms_dispatcher_->video_array()); | 89 ms_dispatcher_->video_array()); |
| 100 | 90 |
| 101 // TODO(perkj): Currently a media stream is identified by its sources. | 91 WebKit::WebMediaStreamDescriptor desc = ms_impl_->last_generated_stream(); |
| 102 // This is currently beeing changed in WebKit. | 92 MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>( |
| 103 // Remove the creation of WebKitSourceVectors when that has landed. | 93 desc.extraData()); |
| 104 if (audio) { | 94 if (!extra_data || !extra_data->local_stream()) { |
| 105 CreateWebKitSourceVector(ms_dispatcher_->stream_label(), | 95 ADD_FAILURE(); |
| 106 ms_dispatcher_->audio_array(), | 96 return desc; |
| 107 WebKit::WebMediaStreamSource::TypeAudio, | |
| 108 audio_sources); | |
| 109 } | 97 } |
| 110 if (video) { | 98 |
| 111 CreateWebKitSourceVector(ms_dispatcher_->stream_label(), | 99 if (audio) |
| 112 ms_dispatcher_->video_array(), | 100 EXPECT_EQ(1u, extra_data->local_stream()->audio_tracks()->count()); |
| 113 WebKit::WebMediaStreamSource::TypeVideo, | 101 if (video) |
| 114 video_sources); | 102 EXPECT_EQ(1u, extra_data->local_stream()->video_tracks()->count()); |
| 115 } | |
| 116 WebKit::WebMediaStreamDescriptor desc; | |
| 117 desc.initialize(UTF8ToUTF16(ms_dispatcher_->stream_label()), | |
| 118 audio_sources, video_sources); | |
| 119 return desc; | 103 return desc; |
| 120 } | 104 } |
| 121 | 105 |
| 122 protected: | 106 protected: |
| 123 MessageLoop loop_; | 107 MessageLoop loop_; |
| 124 scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_; | 108 scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_; |
| 125 scoped_ptr<content::P2PSocketDispatcher> p2p_socket_dispatcher_; | 109 scoped_ptr<content::P2PSocketDispatcher> p2p_socket_dispatcher_; |
| 126 scoped_ptr<MediaStreamImpl> ms_impl_; | 110 scoped_ptr<MediaStreamImplUnderTest> ms_impl_; |
| 127 }; | 111 }; |
| 128 | 112 |
| 129 TEST_F(MediaStreamImplTest, Basic) { | 113 TEST_F(MediaStreamImplTest, Basic) { |
| 114 // Create ROAP PeerConnection. |
| 130 WebKit::MockWebPeerConnectionHandlerClient client; | 115 WebKit::MockWebPeerConnectionHandlerClient client; |
| 131 WebKit::WebPeerConnectionHandler* pc_handler = | 116 scoped_ptr<WebKit::WebPeerConnectionHandler> pc_handler( |
| 132 ms_impl_->CreatePeerConnectionHandler(&client); | 117 ms_impl_->CreatePeerConnectionHandler(&client)); |
| 133 EXPECT_EQ(1u, ms_impl_->peer_connection_handlers_.size()); | 118 pc_handler.reset(); |
| 134 | 119 |
| 135 // Delete PC handler explicitly after closing to mimic WebKit behavior. | 120 // Create JSEP PeerConnection. |
| 136 ms_impl_->ClosePeerConnection( | |
| 137 static_cast<PeerConnectionHandler*>(pc_handler)); | |
| 138 EXPECT_TRUE(ms_impl_->peer_connection_handlers_.empty()); | |
| 139 delete pc_handler; | |
| 140 | |
| 141 WebKit::MockWebPeerConnection00HandlerClient client_jsep; | 121 WebKit::MockWebPeerConnection00HandlerClient client_jsep; |
| 142 WebKit::WebPeerConnection00Handler* pc_handler_jsep = | 122 scoped_ptr<WebKit::WebPeerConnection00Handler> pc_handler_jsep( |
| 143 ms_impl_->CreatePeerConnectionHandlerJsep(&client_jsep); | 123 ms_impl_->CreatePeerConnectionHandlerJsep(&client_jsep)); |
| 144 EXPECT_EQ(1u, ms_impl_->peer_connection_handlers_.size()); | 124 pc_handler_jsep.reset(); |
| 145 | |
| 146 // Delete PC handler explicitly after closing to mimic WebKit behavior. | |
| 147 ms_impl_->ClosePeerConnection( | |
| 148 static_cast<PeerConnectionHandlerJsep*>(pc_handler_jsep)); | |
| 149 EXPECT_TRUE(ms_impl_->peer_connection_handlers_.empty()); | |
| 150 delete pc_handler_jsep; | |
| 151 } | |
| 152 | |
| 153 TEST_F(MediaStreamImplTest, MultiplePeerConnections) { | |
| 154 WebKit::MockWebPeerConnectionHandlerClient client; | |
| 155 WebKit::WebPeerConnectionHandler* pc_handler = | |
| 156 ms_impl_->CreatePeerConnectionHandler(&client); | |
| 157 EXPECT_EQ(1u, ms_impl_->peer_connection_handlers_.size()); | |
| 158 | |
| 159 WebKit::MockWebPeerConnection00HandlerClient client_jsep; | |
| 160 WebKit::WebPeerConnection00Handler* pc_handler_jsep = | |
| 161 ms_impl_->CreatePeerConnectionHandlerJsep(&client_jsep); | |
| 162 EXPECT_EQ(2u, ms_impl_->peer_connection_handlers_.size()); | |
| 163 | |
| 164 // Delete PC handler explicitly after closing to mimic WebKit behavior. | |
| 165 ms_impl_->ClosePeerConnection( | |
| 166 static_cast<PeerConnectionHandler*>(pc_handler)); | |
| 167 EXPECT_EQ(1u, ms_impl_->peer_connection_handlers_.size()); | |
| 168 delete pc_handler; | |
| 169 | |
| 170 // Delete PC handler explicitly after closing to mimic WebKit behavior. | |
| 171 ms_impl_->ClosePeerConnection( | |
| 172 static_cast<PeerConnectionHandlerJsep*>(pc_handler_jsep)); | |
| 173 EXPECT_TRUE(ms_impl_->peer_connection_handlers_.empty()); | |
| 174 delete pc_handler_jsep; | |
| 175 } | 125 } |
| 176 | 126 |
| 177 TEST_F(MediaStreamImplTest, LocalMediaStream) { | 127 TEST_F(MediaStreamImplTest, LocalMediaStream) { |
| 178 // Test a stream with both audio and video. | 128 // Test a stream with both audio and video. |
| 179 WebKit::WebMediaStreamDescriptor mixed_desc = RequestLocalMediaStream(true, | 129 WebKit::WebMediaStreamDescriptor mixed_desc = RequestLocalMediaStream(true, |
| 180 true); | 130 true); |
| 181 webrtc::LocalMediaStreamInterface* mixed_stream = | 131 // Create a renderer for the stream. |
| 182 ms_impl_->GetLocalMediaStream(mixed_desc); | |
| 183 ASSERT_TRUE(mixed_stream != NULL); | |
| 184 EXPECT_EQ(1u, mixed_stream->audio_tracks()->count()); | |
| 185 EXPECT_EQ(1u, mixed_stream->video_tracks()->count()); | |
| 186 | |
| 187 // Create a renderer for the stream | |
| 188 scoped_ptr<media::MessageLoopFactory> message_loop_factory( | 132 scoped_ptr<media::MessageLoopFactory> message_loop_factory( |
| 189 new media::MessageLoopFactory()); | 133 new media::MessageLoopFactory()); |
| 190 scoped_refptr<media::VideoDecoder> mixed_decoder( | 134 scoped_refptr<media::VideoDecoder> mixed_decoder( |
| 191 ms_impl_->CreateLocalVideoDecoder(mixed_stream, | 135 ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); |
| 192 message_loop_factory.get())); | |
| 193 EXPECT_TRUE(mixed_decoder.get() != NULL); | 136 EXPECT_TRUE(mixed_decoder.get() != NULL); |
| 194 | 137 |
| 195 // Test a stream with audio only. | 138 // Test a stream with audio only. |
| 196 WebKit::WebMediaStreamDescriptor audio_desc = RequestLocalMediaStream(true, | 139 WebKit::WebMediaStreamDescriptor audio_desc = RequestLocalMediaStream(true, |
| 197 false); | 140 false); |
| 198 webrtc::LocalMediaStreamInterface* audio_stream = | |
| 199 ms_impl_->GetLocalMediaStream(audio_desc); | |
| 200 ASSERT_TRUE(audio_stream != NULL); | |
| 201 EXPECT_EQ(1u, audio_stream->audio_tracks()->count()); | |
| 202 EXPECT_EQ(0u, audio_stream->video_tracks()->count()); | |
| 203 | |
| 204 scoped_refptr<media::VideoDecoder> audio_decoder( | 141 scoped_refptr<media::VideoDecoder> audio_decoder( |
| 205 ms_impl_->CreateLocalVideoDecoder(audio_stream, | 142 ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); |
| 206 message_loop_factory.get())); | |
| 207 EXPECT_TRUE(audio_decoder.get() == NULL); | 143 EXPECT_TRUE(audio_decoder.get() == NULL); |
| 208 | 144 |
| 209 // Test a stream with video only. | 145 // Test a stream with video only. |
| 210 WebKit::WebMediaStreamDescriptor video_desc = RequestLocalMediaStream(false, | 146 WebKit::WebMediaStreamDescriptor video_desc = RequestLocalMediaStream(false, |
| 211 true); | 147 true); |
| 212 webrtc::LocalMediaStreamInterface* video_stream_ = | |
| 213 ms_impl_->GetLocalMediaStream(video_desc); | |
| 214 ASSERT_TRUE(video_stream_ != NULL); | |
| 215 EXPECT_EQ(0u, video_stream_->audio_tracks()->count()); | |
| 216 EXPECT_EQ(1u, video_stream_->video_tracks()->count()); | |
| 217 | |
| 218 scoped_refptr<media::VideoDecoder> video_decoder( | 148 scoped_refptr<media::VideoDecoder> video_decoder( |
| 219 ms_impl_->CreateLocalVideoDecoder(video_stream_, | 149 ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); |
| 220 message_loop_factory.get())); | |
| 221 EXPECT_TRUE(video_decoder.get() != NULL); | 150 EXPECT_TRUE(video_decoder.get() != NULL); |
| 222 | 151 |
| 223 // Stop generated local streams. | 152 // Stop generated local streams. |
| 224 EXPECT_TRUE(ms_impl_->StopLocalMediaStream(mixed_desc)); | 153 ms_impl_->StopLocalMediaStream(mixed_desc); |
| 225 EXPECT_TRUE(ms_impl_->GetLocalMediaStream(mixed_desc) == NULL); | 154 EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); |
| 226 | 155 ms_impl_->StopLocalMediaStream(audio_desc); |
| 227 EXPECT_TRUE(ms_impl_->StopLocalMediaStream(audio_desc)); | 156 EXPECT_EQ(2, ms_dispatcher_->stop_stream_counter()); |
| 228 EXPECT_TRUE(ms_impl_->GetLocalMediaStream(audio_desc) == NULL); | |
| 229 | 157 |
| 230 // Test that the MediaStreams are deleted if the owning WebFrame is deleted. | 158 // Test that the MediaStreams are deleted if the owning WebFrame is deleted. |
| 231 // In the unit test the owning frame is NULL. | 159 // In the unit test the owning frame is NULL. |
| 232 ms_impl_->FrameWillClose(NULL); | 160 ms_impl_->FrameWillClose(NULL); |
| 233 EXPECT_TRUE(ms_impl_->GetLocalMediaStream(video_desc) == NULL); | 161 EXPECT_EQ(3, ms_dispatcher_->stop_stream_counter()); |
| 234 } | 162 } |
| OLD | NEW |