| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/renderer/media/media_stream_center.h" |
| |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "content/common/media/media_stream_messages.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/renderer/render_thread.h" |
| #include "content/renderer/media/media_stream_dependency_factory.h" |
| #include "content/renderer/media/media_stream_extra_data.h" |
| #include "content/renderer/media/media_stream_source_extra_data.h" |
| #include "content/renderer/media/media_stream_track_extra_data.h" |
| #include "content/renderer/render_view_impl.h" |
| #include "third_party/WebKit/public/platform/WebMediaStream.h" |
| #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h" |
| #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
| #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h" |
| #include "third_party/WebKit/public/platform/WebSourceInfo.h" |
| #include "third_party/WebKit/public/platform/WebVector.h" |
| #include "third_party/WebKit/public/web/WebFrame.h" |
| #include "third_party/libjingle/source/talk/app/webrtc/jsep.h" |
| |
| using blink::WebFrame; |
| using blink::WebView; |
| |
| namespace content { |
| |
| MediaStreamCenter::MediaStreamCenter(blink::WebMediaStreamCenterClient* client, |
| MediaStreamDependencyFactory* factory) |
| : rtc_factory_(factory), next_request_id_(0) {} |
| |
| MediaStreamCenter::~MediaStreamCenter() {} |
| |
| bool MediaStreamCenter::getMediaStreamTrackSources( |
| const blink::WebMediaStreamTrackSourcesRequest& request) { |
| if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kDisableDeviceEnumeration)) { |
| int request_id = next_request_id_++; |
| requests_.insert(std::make_pair(request_id, request)); |
| RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources( |
| request_id, GURL(request.origin().utf8()))); |
| return true; |
| } |
| return false; |
| } |
| |
| void MediaStreamCenter::didCreateMediaStreamTrack( |
| const blink::WebMediaStreamTrack& track) { |
| if (!rtc_factory_) |
| return; |
| rtc_factory_->CreateNativeMediaStreamTrack(track); |
| } |
| |
| void MediaStreamCenter::didEnableMediaStreamTrack( |
| const blink::WebMediaStreamTrack& track) { |
| webrtc::MediaStreamTrackInterface* native_track = |
| MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track); |
| if (native_track) |
| native_track->set_enabled(true); |
| } |
| |
| void MediaStreamCenter::didDisableMediaStreamTrack( |
| const blink::WebMediaStreamTrack& track) { |
| webrtc::MediaStreamTrackInterface* native_track = |
| MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track); |
| if (native_track) |
| native_track->set_enabled(false); |
| } |
| |
| bool MediaStreamCenter::didStopMediaStreamTrack( |
| const blink::WebMediaStreamTrack& track) { |
| DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack"; |
| blink::WebMediaStreamSource source = track.source(); |
| MediaStreamSourceExtraData* extra_data = |
| static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| if (!extra_data) { |
| DVLOG(1) << "didStopMediaStreamTrack called on a remote track."; |
| return false; |
| } |
| |
| extra_data->OnLocalSourceStop(); |
| return true; |
| } |
| |
| void MediaStreamCenter::didStopLocalMediaStream( |
| const blink::WebMediaStream& stream) { |
| DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream"; |
| MediaStreamExtraData* extra_data = |
| static_cast<MediaStreamExtraData*>(stream.extraData()); |
| if (!extra_data) { |
| NOTREACHED(); |
| return; |
| } |
| |
| // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we |
| // need to support the old behavior and the new. Since we only create one |
| // source object per actual device- we need to fake stopping a |
| // MediaStreamTrack by disabling it if the same device is used as source by |
| // multiple tracks. Note that disabling a track here, don't affect the |
| // enabled property in JS. |
| blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; |
| stream.audioTracks(audio_tracks); |
| for (size_t i = 0; i < audio_tracks.size(); ++i) |
| didDisableMediaStreamTrack(audio_tracks[i]); |
| |
| blink::WebVector<blink::WebMediaStreamTrack> video_tracks; |
| stream.videoTracks(video_tracks); |
| for (size_t i = 0; i < video_tracks.size(); ++i) |
| didDisableMediaStreamTrack(video_tracks[i]); |
| |
| extra_data->OnLocalStreamStop(); |
| } |
| |
| void MediaStreamCenter::didCreateMediaStream( |
| blink::WebMediaStream& stream) { |
| if (!rtc_factory_) |
| return; |
| rtc_factory_->CreateNativeLocalMediaStream(&stream); |
| } |
| |
| bool MediaStreamCenter::didAddMediaStreamTrack( |
| const blink::WebMediaStream& stream, |
| const blink::WebMediaStreamTrack& track) { |
| if (!rtc_factory_) |
| return false; |
| |
| return rtc_factory_->AddNativeMediaStreamTrack(stream, track); |
| } |
| |
| bool MediaStreamCenter::didRemoveMediaStreamTrack( |
| const blink::WebMediaStream& stream, |
| const blink::WebMediaStreamTrack& track) { |
| if (!rtc_factory_) |
| return false; |
| |
| return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track); |
| } |
| |
| bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter, message) |
| IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK, |
| OnGetSourcesComplete) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void MediaStreamCenter::OnGetSourcesComplete( |
| int request_id, |
| const content::StreamDeviceInfoArray& devices) { |
| RequestMap::iterator request_it = requests_.find(request_id); |
| DCHECK(request_it != requests_.end()); |
| |
| blink::WebVector<blink::WebSourceInfo> sourceInfos(devices.size()); |
| for (size_t i = 0; i < devices.size(); ++i) { |
| const MediaStreamDevice& device = devices[i].device; |
| DCHECK(device.type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| device.type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| blink::WebSourceInfo::VideoFacingMode video_facing; |
| switch (device.video_facing) { |
| case MEDIA_VIDEO_FACING_USER: |
| video_facing = blink::WebSourceInfo::VideoFacingModeUser; |
| break; |
| case MEDIA_VIDEO_FACING_ENVIRONMENT: |
| video_facing = blink::WebSourceInfo::VideoFacingModeEnvironment; |
| break; |
| default: |
| video_facing = blink::WebSourceInfo::VideoFacingModeNone; |
| } |
| |
| sourceInfos[i] |
| .initialize(blink::WebString::fromUTF8(device.id), |
| device.type == MEDIA_DEVICE_AUDIO_CAPTURE |
| ? blink::WebSourceInfo::SourceKindAudio |
| : blink::WebSourceInfo::SourceKindVideo, |
| blink::WebString::fromUTF8(device.name), |
| video_facing); |
| } |
| request_it->second.requestSucceeded(sourceInfos); |
| } |
| |
| } // namespace content |