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/browser/renderer_host/media/media_stream_dispatcher_host.h"
7 #include "content/browser/browser_main_loop.h"
8 #include "content/browser/renderer_host/media/web_contents_capture_util.h"
9 #include "content/common/media/media_stream_messages.h"
10 #include "content/common/media/media_stream_options.h"
15 MediaStreamDispatcherHost::MediaStreamDispatcherHost(
16 int render_process_id
,
17 ResourceContext
* resource_context
,
18 MediaStreamManager
* media_stream_manager
)
19 : render_process_id_(render_process_id
),
20 resource_context_(resource_context
),
21 media_stream_manager_(media_stream_manager
) {
24 void MediaStreamDispatcherHost::StreamGenerated(
25 const std::string
& label
,
26 const StreamDeviceInfoArray
& audio_devices
,
27 const StreamDeviceInfoArray
& video_devices
) {
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
29 DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerated("
30 << ", {label = " << label
<< "})";
32 StreamRequest request
= PopRequest(label
);
34 Send(new MediaStreamMsg_StreamGenerated(
35 request
.render_view_id
, request
.page_request_id
, label
, audio_devices
,
39 void MediaStreamDispatcherHost::StreamGenerationFailed(
40 const std::string
& label
) {
41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
42 DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerationFailed("
43 << ", {label = " << label
<< "})";
45 StreamRequest request
= PopRequest(label
);
47 Send(new MediaStreamMsg_StreamGenerationFailed(request
.render_view_id
,
48 request
.page_request_id
));
51 void MediaStreamDispatcherHost::DeviceStopped(int render_view_id
,
52 const std::string
& label
,
53 const StreamDeviceInfo
& device
) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
55 DVLOG(1) << "MediaStreamDispatcherHost::DeviceStopped("
56 << "{label = " << label
<< "}, "
57 << "{type = " << device
.device
.type
<< "}, "
58 << "{device_id = " << device
.device
.id
<< "})";
60 Send(new MediaStreamMsg_DeviceStopped(render_view_id
, label
, device
));
63 void MediaStreamDispatcherHost::DevicesEnumerated(
64 const std::string
& label
,
65 const StreamDeviceInfoArray
& devices
) {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
67 DVLOG(1) << "MediaStreamDispatcherHost::DevicesEnumerated("
68 << ", {label = " << label
<< "})";
70 StreamMap::iterator it
= streams_
.find(label
);
71 DCHECK(it
!= streams_
.end());
72 StreamRequest request
= it
->second
;
74 Send(new MediaStreamMsg_DevicesEnumerated(
75 request
.render_view_id
, request
.page_request_id
, devices
));
78 void MediaStreamDispatcherHost::DeviceOpened(
79 const std::string
& label
,
80 const StreamDeviceInfo
& video_device
) {
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
82 DVLOG(1) << "MediaStreamDispatcherHost::DeviceOpened("
83 << ", {label = " << label
<< "})";
85 // TODO(perkj): Checking for StreamRequest here is a temporary fix to avoid
86 // an Assert in PopRequest. Remove this once the real problem is solved.
88 StreamMap::iterator it
= streams_
.find(label
);
89 DCHECK(it
!= streams_
.end());
90 if (it
== streams_
.end()) {
91 LOG(ERROR
) << "DeviceOpened but there is no request for the device.";
95 StreamRequest request
= PopRequest(label
);
97 Send(new MediaStreamMsg_DeviceOpened(
98 request
.render_view_id
, request
.page_request_id
, label
, video_device
));
101 bool MediaStreamDispatcherHost::OnMessageReceived(
102 const IPC::Message
& message
, bool* message_was_ok
) {
104 IPC_BEGIN_MESSAGE_MAP_EX(MediaStreamDispatcherHost
, message
, *message_was_ok
)
105 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_GenerateStream
, OnGenerateStream
)
106 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CancelGenerateStream
,
107 OnCancelGenerateStream
)
108 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_StopStreamDevice
,
110 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_EnumerateDevices
,
112 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CancelEnumerateDevices
,
113 OnCancelEnumerateDevices
)
114 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_OpenDevice
,
116 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CloseDevice
,
118 IPC_MESSAGE_UNHANDLED(handled
= false)
119 IPC_END_MESSAGE_MAP_EX()
123 void MediaStreamDispatcherHost::OnChannelClosing() {
124 DVLOG(1) << "MediaStreamDispatcherHost::OnChannelClosing";
126 // Since the IPC channel is gone, close all requesting/requested streams.
127 media_stream_manager_
->CancelAllRequests(render_process_id_
);
128 // Clear the map after we have stopped all the streams.
132 MediaStreamDispatcherHost::~MediaStreamDispatcherHost() {
133 DCHECK(streams_
.empty());
136 void MediaStreamDispatcherHost::OnGenerateStream(
139 const StreamOptions
& components
,
140 const GURL
& security_origin
) {
141 DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream("
142 << render_view_id
<< ", "
143 << page_request_id
<< ", ["
144 << " audio:" << components
.audio_type
145 << " video:" << components
.video_type
147 << security_origin
.spec() << ")";
149 const std::string
& label
= media_stream_manager_
->GenerateStream(
150 this, render_process_id_
, render_view_id
, resource_context_
,
152 components
, security_origin
);
153 CHECK(!label
.empty());
154 StoreRequest(render_view_id
, page_request_id
, label
);
157 void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_view_id
,
158 int page_request_id
) {
159 DVLOG(1) << "MediaStreamDispatcherHost::OnCancelGenerateStream("
160 << render_view_id
<< ", "
161 << page_request_id
<< ")";
163 for (StreamMap::iterator it
= streams_
.begin(); it
!= streams_
.end(); ++it
) {
164 if (it
->second
.render_view_id
== render_view_id
&&
165 it
->second
.page_request_id
== page_request_id
) {
166 const std::string
& label
= it
->first
;
167 media_stream_manager_
->CancelRequest(label
);
174 void MediaStreamDispatcherHost::OnStopStreamDevice(
176 const std::string
& device_id
) {
177 DVLOG(1) << "MediaStreamDispatcherHost::OnStopStreamDevice("
178 << render_view_id
<< ", "
180 media_stream_manager_
->StopStreamDevice(render_process_id_
, render_view_id
,
184 void MediaStreamDispatcherHost::OnEnumerateDevices(
187 MediaStreamType type
,
188 const GURL
& security_origin
) {
189 DVLOG(1) << "MediaStreamDispatcherHost::OnEnumerateDevices("
190 << render_view_id
<< ", "
191 << page_request_id
<< ", "
193 << security_origin
.spec() << ")";
195 const std::string
& label
= media_stream_manager_
->EnumerateDevices(
196 this, render_process_id_
, render_view_id
, resource_context_
,
197 page_request_id
, type
, security_origin
);
198 StoreRequest(render_view_id
, page_request_id
, label
);
201 void MediaStreamDispatcherHost::OnCancelEnumerateDevices(
203 int page_request_id
) {
204 DVLOG(1) << "MediaStreamDispatcherHost::OnCancelEnumerateDevices("
205 << render_view_id
<< ", "
206 << page_request_id
<< ")";
209 GetRequestLabel(render_view_id
, page_request_id
, &label
);
210 media_stream_manager_
->CancelRequest(label
);
214 void MediaStreamDispatcherHost::OnOpenDevice(
217 const std::string
& device_id
,
218 MediaStreamType type
,
219 const GURL
& security_origin
) {
220 DVLOG(1) << "MediaStreamDispatcherHost::OnOpenDevice("
221 << render_view_id
<< ", "
222 << page_request_id
<< ", device_id: "
223 << device_id
.c_str() << ", type: "
225 << security_origin
.spec() << ")";
227 const std::string
& label
= media_stream_manager_
->OpenDevice(
228 this, render_process_id_
, render_view_id
, resource_context_
,
229 page_request_id
, device_id
, type
, security_origin
);
230 StoreRequest(render_view_id
, page_request_id
, label
);
233 void MediaStreamDispatcherHost::OnCloseDevice(
235 const std::string
& label
) {
236 DVLOG(1) << "MediaStreamDispatcherHost::OnCloseDevice("
237 << render_view_id
<< ", "
240 media_stream_manager_
->CancelRequest(label
);
243 void MediaStreamDispatcherHost::StoreRequest(int render_view_id
,
245 const std::string
& label
) {
246 DCHECK(!label
.empty());
247 DCHECK(streams_
.find(label
) == streams_
.end());
249 streams_
[label
] = StreamRequest(render_view_id
, page_request_id
);
252 MediaStreamDispatcherHost::StreamRequest
253 MediaStreamDispatcherHost::PopRequest(const std::string
& label
) {
254 StreamMap::iterator it
= streams_
.find(label
);
255 CHECK(it
!= streams_
.end());
256 StreamRequest request
= it
->second
;
261 void MediaStreamDispatcherHost::GetRequestLabel(
262 int render_view_id
, int page_request_id
, std::string
* label
) {
263 for (StreamMap::const_iterator it
= streams_
.begin(); it
!= streams_
.end();
265 if (it
->second
.render_view_id
== render_view_id
&&
266 it
->second
.page_request_id
== page_request_id
) {
274 } // namespace content