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 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/media_stream_center.h" 6 7 #include <string> 8 9 #include "base/command_line.h" 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "content/common/media/media_stream_messages.h" 15 #include "content/public/common/content_switches.h" 16 #include "content/public/renderer/render_thread.h" 17 #include "content/renderer/media/media_stream_dependency_factory.h" 18 #include "content/renderer/media/media_stream_extra_data.h" 19 #include "content/renderer/media/media_stream_impl.h" 20 #include "content/renderer/render_view_impl.h" 21 #include "third_party/WebKit/public/platform/WebMediaStream.h" 22 #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h" 23 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 24 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 25 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h" 26 #include "third_party/WebKit/public/platform/WebSourceInfo.h" 27 #include "third_party/WebKit/public/platform/WebVector.h" 28 #include "third_party/WebKit/public/web/WebFrame.h" 29 #include "third_party/libjingle/source/talk/app/webrtc/jsep.h" 30 31 using WebKit::WebFrame; 32 using WebKit::WebView; 33 34 namespace content { 35 36 static webrtc::MediaStreamInterface* GetNativeMediaStream( 37 const WebKit::WebMediaStream& stream) { 38 MediaStreamExtraData* extra_data = 39 static_cast<MediaStreamExtraData*>(stream.extraData()); 40 return extra_data->stream().get(); 41 } 42 43 static webrtc::MediaStreamTrackInterface* GetNativeMediaStreamTrack( 44 const WebKit::WebMediaStream& stream, 45 const WebKit::WebMediaStreamTrack& component) { 46 std::string track_id = UTF16ToUTF8(component.id()); 47 webrtc::MediaStreamInterface* native_stream = GetNativeMediaStream(stream); 48 if (native_stream) { 49 if (component.source().type() == WebKit::WebMediaStreamSource::TypeAudio) { 50 return native_stream->FindAudioTrack(track_id); 51 } 52 if (component.source().type() == WebKit::WebMediaStreamSource::TypeVideo) { 53 return native_stream->FindVideoTrack(track_id); 54 } 55 } 56 NOTREACHED(); 57 return NULL; 58 } 59 60 MediaStreamCenter::MediaStreamCenter(WebKit::WebMediaStreamCenterClient* client, 61 MediaStreamDependencyFactory* factory) 62 : rtc_factory_(factory), next_request_id_(0) {} 63 64 MediaStreamCenter::~MediaStreamCenter() {} 65 66 bool MediaStreamCenter::getMediaStreamTrackSources( 67 const WebKit::WebMediaStreamTrackSourcesRequest& request) { 68 if (!CommandLine::ForCurrentProcess()->HasSwitch( 69 switches::kDisableDeviceEnumeration)) { 70 int request_id = next_request_id_++; 71 requests_.insert(std::make_pair(request_id, request)); 72 RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources( 73 request_id, GURL(request.origin().utf8()))); 74 return true; 75 } 76 return false; 77 } 78 79 void MediaStreamCenter::didEnableMediaStreamTrack( 80 const WebKit::WebMediaStream& stream, 81 const WebKit::WebMediaStreamTrack& component) { 82 webrtc::MediaStreamTrackInterface* track = 83 GetNativeMediaStreamTrack(stream, component); 84 if (track) 85 track->set_enabled(true); 86 } 87 88 void MediaStreamCenter::didDisableMediaStreamTrack( 89 const WebKit::WebMediaStream& stream, 90 const WebKit::WebMediaStreamTrack& component) { 91 webrtc::MediaStreamTrackInterface* track = 92 GetNativeMediaStreamTrack(stream, component); 93 if (track) 94 track->set_enabled(false); 95 } 96 97 void MediaStreamCenter::didStopLocalMediaStream( 98 const WebKit::WebMediaStream& stream) { 99 DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream"; 100 MediaStreamExtraData* extra_data = 101 static_cast<MediaStreamExtraData*>(stream.extraData()); 102 if (!extra_data) { 103 NOTREACHED(); 104 return; 105 } 106 107 extra_data->OnLocalStreamStop(); 108 } 109 110 void MediaStreamCenter::didCreateMediaStream( 111 WebKit::WebMediaStream& stream) { 112 if (!rtc_factory_) 113 return; 114 rtc_factory_->CreateNativeLocalMediaStream(&stream); 115 } 116 117 bool MediaStreamCenter::didAddMediaStreamTrack( 118 const WebKit::WebMediaStream& stream, 119 const WebKit::WebMediaStreamTrack& track) { 120 if (!rtc_factory_) 121 return false; 122 123 return rtc_factory_->AddNativeMediaStreamTrack(stream, track); 124 } 125 126 bool MediaStreamCenter::didRemoveMediaStreamTrack( 127 const WebKit::WebMediaStream& stream, 128 const WebKit::WebMediaStreamTrack& track) { 129 if (!rtc_factory_) 130 return false; 131 132 return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track); 133 } 134 135 bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) { 136 bool handled = true; 137 IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter, message) 138 IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK, 139 OnGetSourcesComplete) 140 IPC_MESSAGE_UNHANDLED(handled = false) 141 IPC_END_MESSAGE_MAP() 142 return handled; 143 } 144 145 void MediaStreamCenter::OnGetSourcesComplete( 146 int request_id, 147 const content::StreamDeviceInfoArray& devices) { 148 RequestMap::iterator request_it = requests_.find(request_id); 149 DCHECK(request_it != requests_.end()); 150 151 WebKit::WebVector<WebKit::WebSourceInfo> sourceInfos(devices.size()); 152 for (size_t i = 0; i < devices.size(); ++i) { 153 DCHECK(devices[i].device.type == MEDIA_DEVICE_AUDIO_CAPTURE || 154 devices[i].device.type == MEDIA_DEVICE_VIDEO_CAPTURE); 155 // TODO(vrk): Hook this up to the device policy so that |device.name| is 156 // only populated when appropriate. 157 sourceInfos[i] 158 .initialize(WebKit::WebString::fromUTF8(devices[i].device.id), 159 devices[i].device.type == MEDIA_DEVICE_AUDIO_CAPTURE 160 ? WebKit::WebSourceInfo::SourceKindAudio 161 : WebKit::WebSourceInfo::SourceKindVideo, 162 WebKit::WebString::fromUTF8(devices[i].device.name), 163 WebKit::WebSourceInfo::VideoFacingModeNone); 164 } 165 request_it->second.requestSucceeded(sourceInfos); 166 } 167 168 } // namespace content 169