| Index: content/renderer/media/media_stream_impl.cc
|
| diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
|
| index 79f86a8321715e245ee946c6755176717983ea24..887b593b9cf42eb91f91e2783d2b82532dcce765 100644
|
| --- a/content/renderer/media/media_stream_impl.cc
|
| +++ b/content/renderer/media/media_stream_impl.cc
|
| @@ -12,6 +12,7 @@
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "content/public/renderer/render_frame.h"
|
| #include "content/renderer/media/media_stream.h"
|
| #include "content/renderer/media/media_stream_audio_source.h"
|
| #include "content/renderer/media/media_stream_dispatcher.h"
|
| @@ -82,15 +83,22 @@ struct MediaStreamImpl::MediaDevicesRequestInfo {
|
| };
|
|
|
| MediaStreamImpl::MediaStreamImpl(
|
| - RenderView* render_view,
|
| - MediaStreamDispatcher* media_stream_dispatcher,
|
| - PeerConnectionDependencyFactory* dependency_factory)
|
| - : RenderViewObserver(render_view),
|
| + RenderFrame* render_frame,
|
| + PeerConnectionDependencyFactory* dependency_factory,
|
| + scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher)
|
| + : RenderFrameObserver(render_frame),
|
| dependency_factory_(dependency_factory),
|
| - media_stream_dispatcher_(media_stream_dispatcher) {
|
| + media_stream_dispatcher_(media_stream_dispatcher.Pass()),
|
| + weak_factory_(this) {
|
| + DCHECK(dependency_factory_);
|
| + DCHECK(media_stream_dispatcher_.get());
|
| }
|
|
|
| MediaStreamImpl::~MediaStreamImpl() {
|
| + // Force-close all outstanding user media requests and local sources here,
|
| + // before the outstanding WeakPtrs are invalidated, to ensure a clean
|
| + // shutdown.
|
| + FrameWillClose();
|
| }
|
|
|
| void MediaStreamImpl::requestUserMedia(
|
| @@ -108,7 +116,6 @@ void MediaStreamImpl::requestUserMedia(
|
|
|
| int request_id = g_next_request_id++;
|
| StreamOptions options;
|
| - blink::WebLocalFrame* frame = NULL;
|
| GURL security_origin;
|
| bool enable_automatic_output_device_selection = false;
|
|
|
| @@ -142,11 +149,9 @@ void MediaStreamImpl::requestUserMedia(
|
| }
|
|
|
| security_origin = GURL(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 = user_media_request.ownerDocument().frame();
|
| - DCHECK(frame);
|
| + DCHECK(render_frame()->GetWebFrame() ==
|
| + static_cast<blink::WebFrame*>(
|
| + user_media_request.ownerDocument().frame()));
|
| }
|
|
|
| DVLOG(1) << "MediaStreamImpl::requestUserMedia(" << request_id << ", [ "
|
| @@ -176,12 +181,12 @@ void MediaStreamImpl::requestUserMedia(
|
| mandatory_video ? "true":"false"));
|
|
|
| user_media_requests_.push_back(
|
| - new UserMediaRequestInfo(request_id, frame, user_media_request,
|
| - enable_automatic_output_device_selection));
|
| + new UserMediaRequestInfo(request_id, user_media_request,
|
| + enable_automatic_output_device_selection));
|
|
|
| media_stream_dispatcher_->GenerateStream(
|
| request_id,
|
| - AsWeakPtr(),
|
| + weak_factory_.GetWeakPtr(),
|
| options,
|
| security_origin);
|
| }
|
| @@ -226,21 +231,21 @@ void MediaStreamImpl::requestMediaDevices(
|
|
|
| media_stream_dispatcher_->EnumerateDevices(
|
| audio_input_request_id,
|
| - AsWeakPtr(),
|
| + weak_factory_.GetWeakPtr(),
|
| MEDIA_DEVICE_AUDIO_CAPTURE,
|
| security_origin,
|
| true);
|
|
|
| media_stream_dispatcher_->EnumerateDevices(
|
| video_input_request_id,
|
| - AsWeakPtr(),
|
| + weak_factory_.GetWeakPtr(),
|
| MEDIA_DEVICE_VIDEO_CAPTURE,
|
| security_origin,
|
| true);
|
|
|
| media_stream_dispatcher_->EnumerateDevices(
|
| audio_output_request_id,
|
| - AsWeakPtr(),
|
| + weak_factory_.GetWeakPtr(),
|
| MEDIA_DEVICE_AUDIO_OUTPUT,
|
| security_origin,
|
| true);
|
| @@ -253,18 +258,7 @@ void MediaStreamImpl::cancelMediaDevicesRequest(
|
| FindMediaDevicesRequestInfo(media_devices_request);
|
| if (!request)
|
| return;
|
| -
|
| - // Cancel device enumeration.
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->audio_input_request_id,
|
| - AsWeakPtr());
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->video_input_request_id,
|
| - AsWeakPtr());
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->audio_output_request_id,
|
| - AsWeakPtr());
|
| - DeleteMediaDevicesRequestInfo(request);
|
| + CancelAndDeleteMediaDevicesRequest(request);
|
| }
|
|
|
| // Callback from MediaStreamDispatcher.
|
| @@ -334,7 +328,8 @@ void MediaStreamImpl::OnStreamGenerated(
|
|
|
| // Wait for the tracks to be started successfully or to fail.
|
| request_info->CallbackOnTracksStarted(
|
| - base::Bind(&MediaStreamImpl::OnCreateNativeTracksCompleted, AsWeakPtr()));
|
| + base::Bind(&MediaStreamImpl::OnCreateNativeTracksCompleted,
|
| + weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| // Callback from MediaStreamDispatcher.
|
| @@ -380,7 +375,7 @@ void MediaStreamImpl::OnDeviceStopped(
|
|
|
| for (LocalStreamSources::iterator device_it = local_sources_.begin();
|
| device_it != local_sources_.end(); ++device_it) {
|
| - if (device_it->source.id() == source.id()) {
|
| + if (device_it->id() == source.id()) {
|
| local_sources_.erase(device_it);
|
| break;
|
| }
|
| @@ -391,7 +386,6 @@ void MediaStreamImpl::InitializeSourceObject(
|
| const StreamDeviceInfo& device,
|
| blink::WebMediaStreamSource::Type type,
|
| const blink::WebMediaConstraints& constraints,
|
| - blink::WebFrame* frame,
|
| blink::WebMediaStreamSource* webkit_source) {
|
| const blink::WebMediaStreamSource* existing_source =
|
| FindLocalSource(device);
|
| @@ -415,18 +409,20 @@ void MediaStreamImpl::InitializeSourceObject(
|
| webkit_source->setExtraData(
|
| CreateVideoSource(
|
| device,
|
| - base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr())));
|
| + base::Bind(&MediaStreamImpl::OnLocalSourceStopped,
|
| + weak_factory_.GetWeakPtr())));
|
| } else {
|
| DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, type);
|
| MediaStreamAudioSource* audio_source(
|
| new MediaStreamAudioSource(
|
| - RenderViewObserver::routing_id(),
|
| + RenderFrameObserver::routing_id(),
|
| device,
|
| - base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()),
|
| + base::Bind(&MediaStreamImpl::OnLocalSourceStopped,
|
| + weak_factory_.GetWeakPtr()),
|
| dependency_factory_));
|
| webkit_source->setExtraData(audio_source);
|
| }
|
| - local_sources_.push_back(LocalStreamSource(frame, *webkit_source));
|
| + local_sources_.push_back(*webkit_source);
|
| }
|
|
|
| MediaStreamVideoSource* MediaStreamImpl::CreateVideoSource(
|
| @@ -450,7 +446,6 @@ void MediaStreamImpl::CreateVideoTracks(
|
| InitializeSourceObject(devices[i],
|
| blink::WebMediaStreamSource::TypeVideo,
|
| constraints,
|
| - request->frame,
|
| &webkit_source);
|
| (*webkit_tracks)[i] =
|
| request->CreateAndStartVideoTrack(webkit_source, constraints);
|
| @@ -491,7 +486,6 @@ void MediaStreamImpl::CreateAudioTracks(
|
| InitializeSourceObject(overridden_audio_array[i],
|
| blink::WebMediaStreamSource::TypeAudio,
|
| constraints,
|
| - request->frame,
|
| &webkit_source);
|
| (*webkit_tracks)[i].initialize(webkit_source);
|
| request->StartAudioTrack((*webkit_tracks)[i], constraints);
|
| @@ -585,19 +579,7 @@ void MediaStreamImpl::OnDevicesEnumerated(
|
| }
|
|
|
| EnumerateDevicesSucceded(&request->request, devices);
|
| -
|
| - // Cancel device enumeration.
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->audio_input_request_id,
|
| - AsWeakPtr());
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->video_input_request_id,
|
| - AsWeakPtr());
|
| - media_stream_dispatcher_->StopEnumerateDevices(
|
| - request->audio_output_request_id,
|
| - AsWeakPtr());
|
| -
|
| - DeleteMediaDevicesRequestInfo(request);
|
| + CancelAndDeleteMediaDevicesRequest(request);
|
| }
|
|
|
| void MediaStreamImpl::OnDeviceOpened(
|
| @@ -672,13 +654,13 @@ const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource(
|
| const StreamDeviceInfo& device) const {
|
| for (LocalStreamSources::const_iterator it = local_sources_.begin();
|
| it != local_sources_.end(); ++it) {
|
| - MediaStreamSource* source =
|
| - static_cast<MediaStreamSource*>(it->source.extraData());
|
| + MediaStreamSource* const source =
|
| + static_cast<MediaStreamSource*>(it->extraData());
|
| const StreamDeviceInfo& active_device = source->device_info();
|
| if (active_device.device.id == device.device.id &&
|
| active_device.device.type == device.device.type &&
|
| active_device.session_id == device.session_id) {
|
| - return &it->source;
|
| + return &(*it);
|
| }
|
| }
|
| return NULL;
|
| @@ -742,11 +724,19 @@ MediaStreamImpl::FindMediaDevicesRequestInfo(
|
| return NULL;
|
| }
|
|
|
| -void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
|
| +void MediaStreamImpl::CancelAndDeleteMediaDevicesRequest(
|
| MediaDevicesRequestInfo* request) {
|
| MediaDevicesRequests::iterator it = media_devices_requests_.begin();
|
| for (; it != media_devices_requests_.end(); ++it) {
|
| if ((*it) == request) {
|
| + // Cancel device enumeration.
|
| + media_stream_dispatcher_->StopEnumerateDevices(
|
| + request->audio_input_request_id, weak_factory_.GetWeakPtr());
|
| + media_stream_dispatcher_->StopEnumerateDevices(
|
| + request->video_input_request_id, weak_factory_.GetWeakPtr());
|
| + media_stream_dispatcher_->StopEnumerateDevices(
|
| + request->audio_output_request_id, weak_factory_.GetWeakPtr());
|
| +
|
| media_devices_requests_.erase(it);
|
| return;
|
| }
|
| @@ -754,43 +744,28 @@ void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
|
| NOTREACHED();
|
| }
|
|
|
| -void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) {
|
| - // Do same thing as FrameWillClose.
|
| - FrameWillClose(frame);
|
| -}
|
| -
|
| -void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) {
|
| - // Loop through all UserMediaRequests and find the requests that belong to the
|
| - // frame that is being closed.
|
| +void MediaStreamImpl::FrameWillClose() {
|
| + // Cancel all outstanding UserMediaRequests.
|
| UserMediaRequests::iterator request_it = user_media_requests_.begin();
|
| while (request_it != user_media_requests_.end()) {
|
| - if ((*request_it)->frame == frame) {
|
| - DVLOG(1) << "MediaStreamImpl::FrameWillClose: "
|
| - << "Cancel user media request " << (*request_it)->request_id;
|
| - // If the request is not generated, it means that a request
|
| - // has been sent to the MediaStreamDispatcher to generate a stream
|
| - // but MediaStreamDispatcher has not yet responded and we need to cancel
|
| - // the request.
|
| - if (!(*request_it)->generated) {
|
| - media_stream_dispatcher_->CancelGenerateStream(
|
| - (*request_it)->request_id, AsWeakPtr());
|
| - }
|
| - request_it = user_media_requests_.erase(request_it);
|
| - } else {
|
| - ++request_it;
|
| + DVLOG(1) << "MediaStreamImpl@" << this << "::FrameWillClose: "
|
| + << "Cancel user media request " << (*request_it)->request_id;
|
| + // If the request is not generated, it means that a request
|
| + // has been sent to the MediaStreamDispatcher to generate a stream
|
| + // but MediaStreamDispatcher has not yet responded and we need to cancel
|
| + // the request.
|
| + if (!(*request_it)->generated) {
|
| + media_stream_dispatcher_->CancelGenerateStream(
|
| + (*request_it)->request_id, weak_factory_.GetWeakPtr());
|
| }
|
| + request_it = user_media_requests_.erase(request_it);
|
| }
|
|
|
| - // Loop through all current local sources and stop the sources that were
|
| - // created by the frame that will be closed.
|
| + // Loop through all current local sources and stop the sources.
|
| LocalStreamSources::iterator sources_it = local_sources_.begin();
|
| while (sources_it != local_sources_.end()) {
|
| - if (sources_it->frame == frame) {
|
| - StopLocalSource(sources_it->source, true);
|
| - sources_it = local_sources_.erase(sources_it);
|
| - } else {
|
| - ++sources_it;
|
| - }
|
| + StopLocalSource(*sources_it, true);
|
| + sources_it = local_sources_.erase(sources_it);
|
| }
|
| }
|
|
|
| @@ -802,7 +777,7 @@ void MediaStreamImpl::OnLocalSourceStopped(
|
| bool device_found = false;
|
| for (LocalStreamSources::iterator device_it = local_sources_.begin();
|
| device_it != local_sources_.end(); ++device_it) {
|
| - if (device_it->source.id() == source.id()) {
|
| + if (device_it->id() == source.id()) {
|
| device_found = true;
|
| local_sources_.erase(device_it);
|
| break;
|
| @@ -811,7 +786,7 @@ void MediaStreamImpl::OnLocalSourceStopped(
|
| CHECK(device_found);
|
|
|
| MediaStreamSource* source_impl =
|
| - static_cast<MediaStreamSource*> (source.extraData());
|
| + static_cast<MediaStreamSource*>(source.extraData());
|
| media_stream_dispatcher_->StopStreamDevice(source_impl->device_info());
|
| }
|
|
|
| @@ -819,7 +794,7 @@ void MediaStreamImpl::StopLocalSource(
|
| const blink::WebMediaStreamSource& source,
|
| bool notify_dispatcher) {
|
| MediaStreamSource* source_impl =
|
| - static_cast<MediaStreamSource*> (source.extraData());
|
| + static_cast<MediaStreamSource*>(source.extraData());
|
| DVLOG(1) << "MediaStreamImpl::StopLocalSource("
|
| << "{device_id = " << source_impl->device_info().device.id << "})";
|
|
|
| @@ -832,14 +807,12 @@ void MediaStreamImpl::StopLocalSource(
|
|
|
| MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
|
| int request_id,
|
| - blink::WebFrame* frame,
|
| const blink::WebUserMediaRequest& request,
|
| bool enable_automatic_output_device_selection)
|
| : request_id(request_id),
|
| generated(false),
|
| enable_automatic_output_device_selection(
|
| enable_automatic_output_device_selection),
|
| - frame(frame),
|
| request(request),
|
| request_failed_(false) {
|
| }
|
|
|