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.
5 #include "content/renderer/media/media_stream_center.h"
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_source.h"
20 #include "content/renderer/media/media_stream_track_extra_data.h"
21 #include "content/renderer/render_view_impl.h"
22 #include "third_party/WebKit/public/platform/WebMediaStream.h"
23 #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h"
24 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
26 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h"
27 #include "third_party/WebKit/public/platform/WebSourceInfo.h"
28 #include "third_party/WebKit/public/platform/WebVector.h"
29 #include "third_party/WebKit/public/web/WebFrame.h"
30 #include "third_party/libjingle/source/talk/app/webrtc/jsep.h"
32 using blink::WebFrame;
37 MediaStreamCenter::MediaStreamCenter(blink::WebMediaStreamCenterClient* client,
38 MediaStreamDependencyFactory* factory)
39 : rtc_factory_(factory), next_request_id_(0) {}
41 MediaStreamCenter::~MediaStreamCenter() {}
43 bool MediaStreamCenter::getMediaStreamTrackSources(
44 const blink::WebMediaStreamTrackSourcesRequest& request) {
45 if (!CommandLine::ForCurrentProcess()->HasSwitch(
46 switches::kDisableDeviceEnumeration)) {
47 int request_id = next_request_id_++;
48 requests_.insert(std::make_pair(request_id, request));
49 RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources(
50 request_id, GURL(request.origin().utf8())));
56 void MediaStreamCenter::didCreateMediaStreamTrack(
57 const blink::WebMediaStreamTrack& track) {
60 rtc_factory_->CreateNativeMediaStreamTrack(track);
63 void MediaStreamCenter::didEnableMediaStreamTrack(
64 const blink::WebMediaStreamTrack& track) {
65 webrtc::MediaStreamTrackInterface* native_track =
66 MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track);
68 native_track->set_enabled(true);
71 void MediaStreamCenter::didDisableMediaStreamTrack(
72 const blink::WebMediaStreamTrack& track) {
73 webrtc::MediaStreamTrackInterface* native_track =
74 MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track);
76 native_track->set_enabled(false);
79 bool MediaStreamCenter::didStopMediaStreamTrack(
80 const blink::WebMediaStreamTrack& track) {
81 DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack";
82 blink::WebMediaStreamSource source = track.source();
83 MediaStreamSource* extra_data =
84 static_cast<MediaStreamSource*>(source.extraData());
86 DVLOG(1) << "didStopMediaStreamTrack called on a remote track.";
90 extra_data->StopSource();
94 void MediaStreamCenter::didStopLocalMediaStream(
95 const blink::WebMediaStream& stream) {
96 DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
97 MediaStreamExtraData* extra_data =
98 static_cast<MediaStreamExtraData*>(stream.extraData());
104 // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we
105 // need to support the old behavior and the new. Since we only create one
106 // source object per actual device- we need to fake stopping a
107 // MediaStreamTrack by disabling it if the same device is used as source by
108 // multiple tracks. Note that disabling a track here, don't affect the
109 // enabled property in JS.
110 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
111 stream.audioTracks(audio_tracks);
112 for (size_t i = 0; i < audio_tracks.size(); ++i)
113 didDisableMediaStreamTrack(audio_tracks[i]);
115 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
116 stream.videoTracks(video_tracks);
117 for (size_t i = 0; i < video_tracks.size(); ++i)
118 didDisableMediaStreamTrack(video_tracks[i]);
120 extra_data->OnLocalStreamStop();
123 void MediaStreamCenter::didCreateMediaStream(
124 blink::WebMediaStream& stream) {
127 rtc_factory_->CreateNativeLocalMediaStream(&stream);
130 bool MediaStreamCenter::didAddMediaStreamTrack(
131 const blink::WebMediaStream& stream,
132 const blink::WebMediaStreamTrack& track) {
136 return rtc_factory_->AddNativeMediaStreamTrack(stream, track);
139 bool MediaStreamCenter::didRemoveMediaStreamTrack(
140 const blink::WebMediaStream& stream,
141 const blink::WebMediaStreamTrack& track) {
145 return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track);
148 bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) {
150 IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter, message)
151 IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK,
152 OnGetSourcesComplete)
153 IPC_MESSAGE_UNHANDLED(handled = false)
154 IPC_END_MESSAGE_MAP()
158 void MediaStreamCenter::OnGetSourcesComplete(
160 const content::StreamDeviceInfoArray& devices) {
161 RequestMap::iterator request_it = requests_.find(request_id);
162 DCHECK(request_it != requests_.end());
164 blink::WebVector<blink::WebSourceInfo> sourceInfos(devices.size());
165 for (size_t i = 0; i < devices.size(); ++i) {
166 const MediaStreamDevice& device = devices[i].device;
167 DCHECK(device.type == MEDIA_DEVICE_AUDIO_CAPTURE ||
168 device.type == MEDIA_DEVICE_VIDEO_CAPTURE);
169 blink::WebSourceInfo::VideoFacingMode video_facing;
170 switch (device.video_facing) {
171 case MEDIA_VIDEO_FACING_USER:
172 video_facing = blink::WebSourceInfo::VideoFacingModeUser;
174 case MEDIA_VIDEO_FACING_ENVIRONMENT:
175 video_facing = blink::WebSourceInfo::VideoFacingModeEnvironment;
178 video_facing = blink::WebSourceInfo::VideoFacingModeNone;
182 .initialize(blink::WebString::fromUTF8(device.id),
183 device.type == MEDIA_DEVICE_AUDIO_CAPTURE
184 ? blink::WebSourceInfo::SourceKindAudio
185 : blink::WebSourceInfo::SourceKindVideo,
186 blink::WebString::fromUTF8(device.name),
189 request_it->second.requestSucceeded(sourceInfos);
192 } // namespace content