summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
authorperkj@chromium.org <perkj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 10:01:37 +0000
committerperkj@chromium.org <perkj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 10:01:37 +0000
commit711e4cb5ac62082a159dfb6f54456f8f552032db (patch)
tree83aad9ce5b30ae7185c42d9434151f5367e78d15 /content/renderer
parentf36871d4b4fc1dd0762080a942fa7a6610c62652 (diff)
downloadchromium_src-711e4cb5ac62082a159dfb6f54456f8f552032db.zip
chromium_src-711e4cb5ac62082a159dfb6f54456f8f552032db.tar.gz
chromium_src-711e4cb5ac62082a159dfb6f54456f8f552032db.tar.bz2
Make sure MediaStreamDispatcher gets notified of stopped streams when a WebFrame is deleted.
BUG= 125938 TEST= unit test and html test pages Review URL: http://codereview.chromium.org/10354009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135311 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/media/media_stream_impl.cc43
-rw-r--r--content/renderer/media/media_stream_impl.h47
-rw-r--r--content/renderer/media/media_stream_impl_unittest.cc10
3 files changed, 77 insertions, 23 deletions
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 8f43e05..c8d9041 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -24,6 +24,7 @@
#include "content/renderer/p2p/socket_dispatcher.h"
#include "jingle/glue/thread_wrapper.h"
#include "media/base/message_loop_factory.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistry.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamComponent.h"
@@ -123,6 +124,7 @@ MediaStreamImpl::MediaStreamImpl(
MediaStreamImpl::~MediaStreamImpl() {
DCHECK(peer_connection_handlers_.empty());
+ DCHECK(local_media_streams_.empty());
if (dependency_factory_.get())
dependency_factory_->ReleasePeerConnectionFactory();
if (network_manager_) {
@@ -212,7 +214,7 @@ webrtc::LocalMediaStreamInterface* MediaStreamImpl::GetLocalMediaStream(
LocalNativeStreamMap::iterator it = local_media_streams_.find(msm_label);
if (it == local_media_streams_.end())
return NULL;
- return it->second.get();
+ return it->second.stream_.get();
}
bool MediaStreamImpl::StopLocalMediaStream(
@@ -241,6 +243,7 @@ void MediaStreamImpl::requestUserMedia(
int request_id = g_next_request_id++;
bool audio = false;
bool video = false;
+ WebKit::WebFrame* frame = NULL;
std::string security_origin;
// |user_media_request| can't be mocked. So in order to test at all we check
@@ -254,6 +257,11 @@ void MediaStreamImpl::requestUserMedia(
video = user_media_request.video();
security_origin = UTF16ToUTF8(
user_media_request.securityOrigin().toString());
+ // Get the WebFrame that requested a MediaStream.
+ // The frame is needed to tell the MediaStreamDispatcher when a stream goes
+ // out of scope.
+ frame = WebKit::WebFrame::frameForCurrentContext();
+ DCHECK(frame);
}
DVLOG(1) << "MediaStreamImpl::generateStream(" << request_id << ", [ "
@@ -261,9 +269,8 @@ void MediaStreamImpl::requestUserMedia(
<< (user_media_request.video() ? " video" : "") << "], "
<< security_origin << ")";
- user_media_requests_.insert(
- std::pair<int, WebKit::WebUserMediaRequest>(
- request_id, user_media_request));
+ user_media_requests_[request_id] =
+ UserMediaRequestInfo(frame, user_media_request);
media_stream_dispatcher_->GenerateStream(
request_id,
@@ -330,9 +337,10 @@ void MediaStreamImpl::OnStreamGenerated(
return;
}
- CreateNativeLocalMediaStream(label, audio_source_vector, video_source_vector);
+ CreateNativeLocalMediaStream(label, it->second.frame_,
+ audio_source_vector, video_source_vector);
- WebKit::WebUserMediaRequest user_media_request(it->second);
+ WebKit::WebUserMediaRequest user_media_request(it->second.request_);
user_media_requests_.erase(it);
// |user_media_request| can't be mocked. So in order to test at all we check
@@ -351,7 +359,7 @@ void MediaStreamImpl::OnStreamGenerationFailed(int request_id) {
DVLOG(1) << "Request ID not found";
return;
}
- WebKit::WebUserMediaRequest user_media_request = it->second;
+ WebKit::WebUserMediaRequest user_media_request(it->second.request_);
user_media_requests_.erase(it);
user_media_request.requestFailed();
@@ -404,6 +412,21 @@ void MediaStreamImpl::OnDeviceOpenFailed(int request_id) {
NOTIMPLEMENTED();
}
+void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) {
+ LocalNativeStreamMap::iterator it = local_media_streams_.begin();
+ while (it != local_media_streams_.end()) {
+ if (it->second.frame_ == frame) {
+ DVLOG(1) << "MediaStreamImpl::FrameWillClose: "
+ << "Stopping stream " << it->first;
+ media_stream_dispatcher_->StopStream(it->first);
+ local_media_streams_.erase(it);
+ it = local_media_streams_.begin();
+ } else {
+ ++it;
+ }
+ }
+}
+
void MediaStreamImpl::InitializeWorkerThread(talk_base::Thread** thread,
base::WaitableEvent* event) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
@@ -537,6 +560,7 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateRemoteVideoDecoder(
void MediaStreamImpl::CreateNativeLocalMediaStream(
const std::string& label,
+ WebKit::WebFrame* frame,
const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources,
const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources) {
// Creating the peer connection factory can fail if for example the audio
@@ -574,7 +598,7 @@ void MediaStreamImpl::CreateNativeLocalMediaStream(
UTF16ToUTF8(video_sources[i].name()), video_session_id));
native_stream->AddTrack(video_track);
}
- local_media_streams_[label] = native_stream;
+ local_media_streams_[label] = LocalMediaStreamInfo(frame, native_stream);
}
MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper(
@@ -584,3 +608,6 @@ MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper(
MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {
}
+
+MediaStreamImpl::LocalMediaStreamInfo::~LocalMediaStreamInfo() {
+}
diff --git a/content/renderer/media/media_stream_impl.h b/content/renderer/media/media_stream_impl.h
index 37af40c0..c1206c0 100644
--- a/content/renderer/media/media_stream_impl.h
+++ b/content/renderer/media/media_stream_impl.h
@@ -44,6 +44,7 @@ class Thread;
}
namespace WebKit {
+class WebFrame;
class WebMediaStreamComponent;
class WebMediaStreamDescriptor;
class WebPeerConnection00Handler;
@@ -129,6 +130,9 @@ class CONTENT_EXPORT MediaStreamImpl
const media_stream::StreamDeviceInfo& device_info) OVERRIDE;
virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
+ // content::RenderViewObserver OVERRIDE
+ virtual void FrameWillClose(WebKit::WebFrame* frame) OVERRIDE;
+
private:
FRIEND_TEST_ALL_PREFIXES(MediaStreamImplTest, Basic);
FRIEND_TEST_ALL_PREFIXES(MediaStreamImplTest, MultiplePeerConnections);
@@ -148,6 +152,36 @@ class CONTENT_EXPORT MediaStreamImpl
scoped_refptr<RTCVideoDecoder> rtc_video_decoder_;
};
+ // Structure for storing information about a WebKit request to create a
+ // MediaStream.
+ struct UserMediaRequestInfo {
+ UserMediaRequestInfo() : frame_(NULL), request_() {}
+ UserMediaRequestInfo(WebKit::WebFrame* frame,
+ const WebKit::WebUserMediaRequest& request)
+ : frame_(frame), request_(request) {}
+ WebKit::WebFrame* frame_; // WebFrame that requested the MediaStream.
+ WebKit::WebUserMediaRequest request_;
+ };
+ typedef std::map<int, UserMediaRequestInfo> MediaRequestMap;
+
+ // We keep a list of the generated local media streams,
+ // so that we can enable and disable individual tracks and add renderers
+ // when needed.
+ typedef talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface>
+ LocalMediaStreamPtr;
+ struct LocalMediaStreamInfo {
+ LocalMediaStreamInfo() : frame_(NULL), stream_() {}
+ LocalMediaStreamInfo(WebKit::WebFrame* frame,
+ webrtc::LocalMediaStreamInterface* stream)
+ : frame_(frame), stream_(stream) {}
+ ~LocalMediaStreamInfo();
+ // WebFrame that requested the Stream.
+ WebKit::WebFrame* frame_;
+ // Native representation of a local MediaStream.
+ LocalMediaStreamPtr stream_;
+ };
+ typedef std::map<std::string, LocalMediaStreamInfo> LocalNativeStreamMap;
+
void InitializeWorkerThread(talk_base::Thread** thread,
base::WaitableEvent* event);
@@ -168,6 +202,7 @@ class CONTENT_EXPORT MediaStreamImpl
media::MessageLoopFactory* message_loop_factory);
void CreateNativeLocalMediaStream(
const std::string& label,
+ WebKit::WebFrame* frame,
const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources,
const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources);
@@ -184,9 +219,7 @@ class CONTENT_EXPORT MediaStreamImpl
// We own network_manager_, must be deleted on the worker thread.
// The network manager uses |p2p_socket_dispatcher_|.
content::IpcNetworkManager* network_manager_;
-
scoped_ptr<content::IpcPacketSocketFactory> socket_factory_;
-
scoped_refptr<VideoCaptureImplManager> vc_manager_;
// peer_connection_handlers_ contains raw references, owned by WebKit. A
@@ -194,12 +227,7 @@ class CONTENT_EXPORT MediaStreamImpl
// ClosePeerConnection on us and we remove the pointer).
std::list<PeerConnectionHandlerBase*> peer_connection_handlers_;
- // We keep a list of the generated local media streams,
- // so that we can enable and disable individual tracks and add renderers
- // when needed.
- typedef talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface>
- LocalMediaStreamPtr;
- typedef std::map<std::string, LocalMediaStreamPtr> LocalNativeStreamMap;
+ MediaRequestMap user_media_requests_;
LocalNativeStreamMap local_media_streams_;
// PeerConnection threads. signaling_thread_ is created from the
@@ -208,9 +236,6 @@ class CONTENT_EXPORT MediaStreamImpl
talk_base::Thread* worker_thread_;
base::Thread chrome_worker_thread_;
- typedef std::map<int, WebKit::WebUserMediaRequest> MediaRequestMap;
- MediaRequestMap user_media_requests_;
-
DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
};
diff --git a/content/renderer/media/media_stream_impl_unittest.cc b/content/renderer/media/media_stream_impl_unittest.cc
index 2505910..40797f6 100644
--- a/content/renderer/media/media_stream_impl_unittest.cc
+++ b/content/renderer/media/media_stream_impl_unittest.cc
@@ -83,8 +83,8 @@ class MediaStreamImplTest : public ::testing::Test {
loop_.RunAllPending();
}
- WebKit::WebMediaStreamDescriptor RequestLocalMediaStream (bool audio,
- bool video) {
+ WebKit::WebMediaStreamDescriptor RequestLocalMediaStream(bool audio,
+ bool video) {
WebKit::WebUserMediaRequest user_media_request;
WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources(
audio ? static_cast<size_t>(1) : 0);
@@ -220,13 +220,15 @@ TEST_F(MediaStreamImplTest, LocalMediaStream) {
message_loop_factory.get()));
EXPECT_TRUE(video_decoder.get() != NULL);
- // Stop all generated local streams.
+ // Stop generated local streams.
EXPECT_TRUE(ms_impl_->StopLocalMediaStream(mixed_desc));
EXPECT_TRUE(ms_impl_->GetLocalMediaStream(mixed_desc) == NULL);
EXPECT_TRUE(ms_impl_->StopLocalMediaStream(audio_desc));
EXPECT_TRUE(ms_impl_->GetLocalMediaStream(audio_desc) == NULL);
- EXPECT_TRUE(ms_impl_->StopLocalMediaStream(video_desc));
+ // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
+ // In the unit test the owning frame is NULL.
+ ms_impl_->FrameWillClose(NULL);
EXPECT_TRUE(ms_impl_->GetLocalMediaStream(video_desc) == NULL);
}