| 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 e1bb11196e0a3830eac72eff46bf3c17cf0a2cfe..d576a68edc4a9248a610ed2162f530d0efef0d73 100644
|
| --- a/content/renderer/media/media_stream_impl.cc
|
| +++ b/content/renderer/media/media_stream_impl.cc
|
| @@ -22,6 +22,7 @@
|
| #include "content/renderer/media/webrtc_uma_histograms.h"
|
| #include "content/renderer/render_thread_impl.h"
|
| #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
|
| +#include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
|
| #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
|
| #include "third_party/WebKit/public/web/WebDocument.h"
|
| #include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| @@ -53,6 +54,25 @@ static int g_next_request_id = 0;
|
|
|
| } // namespace
|
|
|
| +struct MediaStreamImpl::MediaDevicesRequestInfo {
|
| + MediaDevicesRequestInfo(const blink::WebMediaDevicesRequest& request,
|
| + int audio_input_request_id,
|
| + int video_input_request_id)
|
| + : request(request),
|
| + audio_input_request_id(audio_input_request_id),
|
| + video_input_request_id(video_input_request_id),
|
| + has_audio_input_returned(false),
|
| + has_video_input_returned(false) {}
|
| +
|
| + blink::WebMediaDevicesRequest request;
|
| + int audio_input_request_id;
|
| + int video_input_request_id;
|
| + bool has_audio_input_returned;
|
| + bool has_video_input_returned;
|
| + StreamDeviceInfoArray audio_input_devices;
|
| + StreamDeviceInfoArray video_input_devices;
|
| +};
|
| +
|
| MediaStreamImpl::MediaStreamImpl(
|
| RenderView* render_view,
|
| MediaStreamDispatcher* media_stream_dispatcher,
|
| @@ -170,6 +190,59 @@ void MediaStreamImpl::cancelUserMediaRequest(
|
| }
|
| }
|
|
|
| +void MediaStreamImpl::requestMediaDevices(
|
| + const blink::WebMediaDevicesRequest& media_devices_request) {
|
| + UpdateWebRTCMethodCount(WEBKIT_GET_MEDIA_DEVICES);
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| + int audio_input_request_id = g_next_request_id++;
|
| + int video_input_request_id = g_next_request_id++;
|
| +
|
| + // |media_devices_request| can't be mocked, so in tests it will be empty (the
|
| + // underlying pointer is null). In order to use this function in a test we
|
| + // need to check if it isNull.
|
| + GURL security_origin;
|
| + if (!media_devices_request.isNull())
|
| + security_origin = GURL(media_devices_request.securityOrigin().toString());
|
| +
|
| + DVLOG(1) << "MediaStreamImpl::requestMediaDevices(" << audio_input_request_id
|
| + << ", " << video_input_request_id << ", "
|
| + << security_origin.spec() << ")";
|
| +
|
| + media_devices_requests_.push_back(new MediaDevicesRequestInfo(
|
| + media_devices_request, audio_input_request_id, video_input_request_id));
|
| +
|
| + media_stream_dispatcher_->EnumerateDevices(
|
| + audio_input_request_id,
|
| + AsWeakPtr(),
|
| + MEDIA_DEVICE_AUDIO_CAPTURE,
|
| + security_origin);
|
| +
|
| + media_stream_dispatcher_->EnumerateDevices(
|
| + video_input_request_id,
|
| + AsWeakPtr(),
|
| + MEDIA_DEVICE_VIDEO_CAPTURE,
|
| + security_origin);
|
| +}
|
| +
|
| +void MediaStreamImpl::cancelMediaDevicesRequest(
|
| + const blink::WebMediaDevicesRequest& media_devices_request) {
|
| + DCHECK(CalledOnValidThread());
|
| + MediaDevicesRequestInfo* request =
|
| + 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());
|
| + DeleteMediaDevicesRequestInfo(request);
|
| +}
|
| +
|
| // Callback from MediaStreamDispatcher.
|
| // The requested stream have been generated by the MediaStreamDispatcher.
|
| void MediaStreamImpl::OnStreamGenerated(
|
| @@ -418,9 +491,63 @@ void MediaStreamImpl::OnCreateNativeTracksCompleted(
|
| void MediaStreamImpl::OnDevicesEnumerated(
|
| int request_id,
|
| const StreamDeviceInfoArray& device_array) {
|
| - DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated("
|
| - << request_id << ")";
|
| - NOTIMPLEMENTED();
|
| + DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" << request_id << ")";
|
| +
|
| + MediaDevicesRequestInfo* request = FindMediaDevicesRequestInfo(request_id);
|
| + DCHECK(request);
|
| +
|
| + if (request_id == request->audio_input_request_id) {
|
| + request->has_audio_input_returned = true;
|
| + DCHECK(request->audio_input_devices.empty());
|
| + request->audio_input_devices = device_array;
|
| + } else {
|
| + DCHECK(request_id == request->video_input_request_id);
|
| + request->has_video_input_returned = true;
|
| + DCHECK(request->video_input_devices.empty());
|
| + request->video_input_devices = device_array;
|
| + }
|
| +
|
| + if (!request->has_audio_input_returned ||
|
| + !request->has_video_input_returned) {
|
| + // Wait for the rest of the devices to complete.
|
| + return;
|
| + }
|
| +
|
| + // Both audio and video devices are ready for copying.
|
| + // TODO(grunell): Add support for output devices and group id.
|
| + blink::WebVector<blink::WebMediaDeviceInfo>
|
| + devices(request->audio_input_devices.size() +
|
| + request->video_input_devices.size());
|
| + for (size_t i = 0; i < request->audio_input_devices.size(); ++i) {
|
| + const MediaStreamDevice& device = request->audio_input_devices[i].device;
|
| + DCHECK_EQ(device.type, MEDIA_DEVICE_AUDIO_CAPTURE);
|
| + devices[i].initialize(blink::WebString::fromUTF8(device.id),
|
| + blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput,
|
| + blink::WebString::fromUTF8(device.name),
|
| + blink::WebString());
|
| + }
|
| + size_t audio_size = request->audio_input_devices.size();
|
| + for (size_t i = 0; i < request->video_input_devices.size(); ++i) {
|
| + const MediaStreamDevice& device = request->video_input_devices[i].device;
|
| + DCHECK_EQ(device.type, MEDIA_DEVICE_VIDEO_CAPTURE);
|
| + devices[audio_size + i].initialize(
|
| + blink::WebString::fromUTF8(device.id),
|
| + blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
|
| + blink::WebString::fromUTF8(device.name),
|
| + blink::WebString());
|
| + }
|
| +
|
| + 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());
|
| +
|
| + DeleteMediaDevicesRequestInfo(request);
|
| }
|
|
|
| void MediaStreamImpl::OnDeviceOpened(
|
| @@ -485,6 +612,12 @@ void MediaStreamImpl::GetUserMediaRequestFailed(
|
| }
|
| }
|
|
|
| +void MediaStreamImpl::EnumerateDevicesSucceded(
|
| + blink::WebMediaDevicesRequest* request,
|
| + blink::WebVector<blink::WebMediaDeviceInfo>& devices) {
|
| + request->requestSucceeded(devices);
|
| +}
|
| +
|
| const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource(
|
| const StreamDeviceInfo& device) const {
|
| for (LocalStreamSources::const_iterator it = local_sources_.begin();
|
| @@ -534,6 +667,42 @@ void MediaStreamImpl::DeleteUserMediaRequestInfo(
|
| NOTREACHED();
|
| }
|
|
|
| +MediaStreamImpl::MediaDevicesRequestInfo*
|
| +MediaStreamImpl::FindMediaDevicesRequestInfo(
|
| + int request_id) {
|
| + MediaDevicesRequests::iterator it = media_devices_requests_.begin();
|
| + for (; it != media_devices_requests_.end(); ++it) {
|
| + if ((*it)->audio_input_request_id == request_id ||
|
| + (*it)->video_input_request_id == request_id) {
|
| + return (*it);
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +MediaStreamImpl::MediaDevicesRequestInfo*
|
| +MediaStreamImpl::FindMediaDevicesRequestInfo(
|
| + const blink::WebMediaDevicesRequest& request) {
|
| + MediaDevicesRequests::iterator it = media_devices_requests_.begin();
|
| + for (; it != media_devices_requests_.end(); ++it) {
|
| + if ((*it)->request == request)
|
| + return (*it);
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
|
| + MediaDevicesRequestInfo* request) {
|
| + MediaDevicesRequests::iterator it = media_devices_requests_.begin();
|
| + for (; it != media_devices_requests_.end(); ++it) {
|
| + if ((*it) == request) {
|
| + media_devices_requests_.erase(it);
|
| + return;
|
| + }
|
| + }
|
| + NOTREACHED();
|
| +}
|
| +
|
| void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) {
|
| // Do same thing as FrameWillClose.
|
| FrameWillClose(frame);
|
|
|