- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / media_stream_center.cc
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_source_extra_data.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 MediaStreamCenter::MediaStreamCenter(WebKit::WebMediaStreamCenterClient* client,
37                                      MediaStreamDependencyFactory* factory)
38     : rtc_factory_(factory), next_request_id_(0) {}
39
40 MediaStreamCenter::~MediaStreamCenter() {}
41
42 bool MediaStreamCenter::getMediaStreamTrackSources(
43     const WebKit::WebMediaStreamTrackSourcesRequest& request) {
44   if (!CommandLine::ForCurrentProcess()->HasSwitch(
45       switches::kDisableDeviceEnumeration)) {
46     int request_id = next_request_id_++;
47     requests_.insert(std::make_pair(request_id, request));
48     RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources(
49         request_id, GURL(request.origin().utf8())));
50     return true;
51   }
52   return false;
53 }
54
55 void MediaStreamCenter::didEnableMediaStreamTrack(
56     const WebKit::WebMediaStream& stream,
57     const WebKit::WebMediaStreamTrack& component) {
58   webrtc::MediaStreamTrackInterface* track =
59       MediaStreamDependencyFactory::GetNativeMediaStreamTrack(component);
60   if (track)
61     track->set_enabled(true);
62 }
63
64 void MediaStreamCenter::didDisableMediaStreamTrack(
65     const WebKit::WebMediaStream& stream,
66     const WebKit::WebMediaStreamTrack& component) {
67   webrtc::MediaStreamTrackInterface* track =
68       MediaStreamDependencyFactory::GetNativeMediaStreamTrack(component);
69   if (track)
70     track->set_enabled(false);
71 }
72
73 bool MediaStreamCenter::didStopMediaStreamTrack(
74     const WebKit::WebMediaStreamTrack& web_track) {
75   DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack";
76   WebKit::WebMediaStreamSource web_source = web_track.source();
77   MediaStreamSourceExtraData* extra_data =
78       static_cast<MediaStreamSourceExtraData*>(web_source.extraData());
79   if (!extra_data) {
80     DVLOG(1) << "didStopMediaStreamTrack called on a remote track.";
81     return false;
82   }
83
84   extra_data->OnLocalSourceStop();
85   return true;
86 }
87
88 void MediaStreamCenter::didStopLocalMediaStream(
89     const WebKit::WebMediaStream& stream) {
90   DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
91   MediaStreamExtraData* extra_data =
92       static_cast<MediaStreamExtraData*>(stream.extraData());
93   if (!extra_data) {
94     NOTREACHED();
95     return;
96   }
97
98   // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we
99   // need to support the old behavior and the new. Since we only create one
100   // source object per actual device- we need to fake stopping a
101   // MediaStreamTrack by disabling it if the same device is used as source by
102   // multiple tracks. Note that disabling a track here, don't affect the
103   // enabled property in JS.
104   WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
105   stream.audioTracks(audio_tracks);
106   for (size_t i = 0; i < audio_tracks.size(); ++i)
107     didDisableMediaStreamTrack(stream, audio_tracks[i]);
108
109   WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
110   stream.videoTracks(video_tracks);
111   for (size_t i = 0; i < video_tracks.size(); ++i)
112     didDisableMediaStreamTrack(stream, video_tracks[i]);
113
114   extra_data->OnLocalStreamStop();
115 }
116
117 void MediaStreamCenter::didCreateMediaStream(
118     WebKit::WebMediaStream& stream) {
119   if (!rtc_factory_)
120     return;
121   rtc_factory_->CreateNativeLocalMediaStream(&stream);
122 }
123
124 bool MediaStreamCenter::didAddMediaStreamTrack(
125     const WebKit::WebMediaStream& stream,
126     const WebKit::WebMediaStreamTrack& track) {
127   if (!rtc_factory_)
128     return false;
129
130   return rtc_factory_->AddNativeMediaStreamTrack(stream, track);
131 }
132
133 bool MediaStreamCenter::didRemoveMediaStreamTrack(
134     const WebKit::WebMediaStream& stream,
135     const WebKit::WebMediaStreamTrack& track) {
136   if (!rtc_factory_)
137     return false;
138
139   return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track);
140 }
141
142 bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) {
143   bool handled = true;
144   IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter, message)
145     IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK,
146                         OnGetSourcesComplete)
147     IPC_MESSAGE_UNHANDLED(handled = false)
148   IPC_END_MESSAGE_MAP()
149   return handled;
150 }
151
152 void MediaStreamCenter::OnGetSourcesComplete(
153     int request_id,
154     const content::StreamDeviceInfoArray& devices) {
155   RequestMap::iterator request_it = requests_.find(request_id);
156   DCHECK(request_it != requests_.end());
157
158   WebKit::WebVector<WebKit::WebSourceInfo> sourceInfos(devices.size());
159   for (size_t i = 0; i < devices.size(); ++i) {
160     const MediaStreamDevice& device = devices[i].device;
161     DCHECK(device.type == MEDIA_DEVICE_AUDIO_CAPTURE ||
162            device.type == MEDIA_DEVICE_VIDEO_CAPTURE);
163     WebKit::WebSourceInfo::VideoFacingMode video_facing;
164     switch (device.video_facing) {
165       case MEDIA_VIDEO_FACING_USER:
166         video_facing = WebKit::WebSourceInfo::VideoFacingModeUser;
167         break;
168       case MEDIA_VIDEO_FACING_ENVIRONMENT:
169         video_facing = WebKit::WebSourceInfo::VideoFacingModeEnvironment;
170         break;
171       default:
172         video_facing = WebKit::WebSourceInfo::VideoFacingModeNone;
173     }
174
175     sourceInfos[i]
176         .initialize(WebKit::WebString::fromUTF8(device.id),
177                     device.type == MEDIA_DEVICE_AUDIO_CAPTURE
178                         ? WebKit::WebSourceInfo::SourceKindAudio
179                         : WebKit::WebSourceInfo::SourceKindVideo,
180                     WebKit::WebString::fromUTF8(device.name),
181                     video_facing);
182   }
183   request_it->second.requestSucceeded(sourceInfos);
184 }
185
186 }  // namespace content