OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/media/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 if (stream_type == kVideoCapture && | 43 if (stream_type == kVideoCapture && |
44 (options.video_option != StreamOptions::kNoCamera)) { | 44 (options.video_option != StreamOptions::kNoCamera)) { |
45 return true; | 45 return true; |
46 } else if (stream_type == kAudioCapture && options.audio == true) { | 46 } else if (stream_type == kAudioCapture && options.audio == true) { |
47 return true; | 47 return true; |
48 } | 48 } |
49 return false; | 49 return false; |
50 } | 50 } |
51 | 51 |
52 struct MediaStreamManager::DeviceRequest { | 52 struct MediaStreamManager::DeviceRequest { |
53 DeviceRequest() | |
54 : requester(NULL), | |
55 state(kNumMediaStreamTypes, kNotRequested) { | |
56 options.audio = false; | |
57 options.video_option = StreamOptions::kNoCamera; | |
58 } | |
59 DeviceRequest(MediaStreamRequester* requester, | |
60 const StreamOptions& request_options) | |
61 : requester(requester), | |
62 options(request_options), | |
63 state(kNumMediaStreamTypes, kNotRequested) { | |
64 DCHECK(requester); | |
65 } | |
66 ~DeviceRequest() {} | |
67 | |
68 enum RequestState { | 53 enum RequestState { |
69 kNotRequested = 0, | 54 kNotRequested = 0, |
70 kRequested, | 55 kRequested, |
71 kOpening, | 56 kOpening, |
72 kDone, | 57 kDone, |
73 kError | 58 kError |
74 }; | 59 }; |
75 | 60 |
61 enum RequestType { | |
62 kGenerateStream = 0, | |
63 kEnumerateVideoDevices, | |
64 kOpenVideoDevice | |
65 }; | |
66 | |
67 DeviceRequest() | |
68 : requester(NULL), | |
69 state(kNumMediaStreamTypes, kNotRequested), | |
70 type(kGenerateStream) { | |
71 options.audio = false; | |
72 options.video_option = StreamOptions::kNoCamera; | |
73 } | |
74 | |
75 DeviceRequest(MediaStreamRequester* requester, | |
76 const StreamOptions& request_options) | |
77 : requester(requester), | |
78 options(request_options), | |
79 state(kNumMediaStreamTypes, kNotRequested), | |
80 type(kGenerateStream) { | |
81 DCHECK(requester); | |
82 } | |
83 | |
84 ~DeviceRequest() {} | |
85 | |
76 MediaStreamRequester* requester; | 86 MediaStreamRequester* requester; |
77 StreamOptions options; | 87 StreamOptions options; |
78 std::vector<RequestState> state; | 88 std::vector<RequestState> state; |
89 RequestType type; | |
90 std::string requested_device_id; | |
79 StreamDeviceInfoArray audio_devices; | 91 StreamDeviceInfoArray audio_devices; |
80 StreamDeviceInfoArray video_devices; | 92 StreamDeviceInfoArray video_devices; |
81 }; | 93 }; |
82 | 94 |
83 MediaStreamManager::MediaStreamManager() | 95 MediaStreamManager::MediaStreamManager() |
84 : ALLOW_THIS_IN_INITIALIZER_LIST( | 96 : ALLOW_THIS_IN_INITIALIZER_LIST( |
85 device_settings_(new MediaStreamDeviceSettings(this))), | 97 device_settings_(new MediaStreamDeviceSettings(this))), |
86 enumeration_in_progress_(kNumMediaStreamTypes, false) { | 98 enumeration_in_progress_(kNumMediaStreamTypes, false) { |
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
88 } | 100 } |
(...skipping 23 matching lines...) Expand all Loading... | |
112 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 124 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, |
113 int render_process_id, | 125 int render_process_id, |
114 int render_view_id, | 126 int render_view_id, |
115 const StreamOptions& options, | 127 const StreamOptions& options, |
116 const std::string& security_origin, | 128 const std::string& security_origin, |
117 std::string* label) { | 129 std::string* label) { |
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
119 | 131 |
120 // Create a new request based on options. | 132 // Create a new request based on options. |
121 DeviceRequest new_request = DeviceRequest(requester, options); | 133 DeviceRequest new_request = DeviceRequest(requester, options); |
122 if (Requested(new_request.options, kAudioCapture)) { | 134 StartEnumeration(&new_request, render_process_id, render_view_id, |
123 new_request.state[kAudioCapture] = DeviceRequest::kRequested; | 135 security_origin, label); |
124 } | |
125 if (Requested(new_request.options, kVideoCapture)) { | |
126 new_request.state[kVideoCapture] = DeviceRequest::kRequested; | |
127 } | |
128 | |
129 // Create a label for this request and verify it is unique. | |
130 std::string request_label; | |
131 do { | |
132 request_label = RandomLabel(); | |
133 } while (requests_.find(request_label) != requests_.end()); | |
134 | |
135 requests_.insert(std::make_pair(request_label, new_request)); | |
136 | |
137 // Get user confirmation to use capture devices. | |
138 // Need to make an asynchronous call to make sure the |requester| gets the | |
139 // |label| before it would receive any event. | |
140 BrowserThread::PostTask( | |
141 BrowserThread::IO, | |
142 FROM_HERE, | |
143 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | |
144 base::Unretained(device_settings_.get()), | |
145 request_label, render_process_id, | |
146 render_view_id, options, | |
147 security_origin)); | |
148 | |
149 (*label) = request_label; | |
150 } | 136 } |
151 | 137 |
152 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { | 138 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { |
153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
154 DeviceRequests::iterator it = requests_.begin(); | 140 DeviceRequests::iterator it = requests_.begin(); |
155 while (it != requests_.end()) { | 141 while (it != requests_.end()) { |
156 if (it->second.requester == requester && !RequestDone(it->second)) { | 142 if (it->second.requester == requester && !RequestDone(it->second)) { |
157 // The request isn't complete, but there might be some devices already | 143 // The request isn't complete, but there might be some devices already |
158 // opened -> close them. | 144 // opened -> close them. |
159 DeviceRequest* request = &(it->second); | 145 DeviceRequest* request = &(it->second); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 for (StreamDeviceInfoArray::iterator video_it = | 181 for (StreamDeviceInfoArray::iterator video_it = |
196 it->second.video_devices.begin(); | 182 it->second.video_devices.begin(); |
197 video_it != it->second.video_devices.end(); ++video_it) { | 183 video_it != it->second.video_devices.end(); ++video_it) { |
198 video_capture_manager()->Close(video_it->session_id); | 184 video_capture_manager()->Close(video_it->session_id); |
199 } | 185 } |
200 requests_.erase(it); | 186 requests_.erase(it); |
201 return; | 187 return; |
202 } | 188 } |
203 } | 189 } |
204 | 190 |
191 void MediaStreamManager::EnumerateVideoDevices( | |
192 MediaStreamRequester* requester, | |
193 int render_process_id, | |
194 int render_view_id, | |
195 const std::string& security_origin, | |
196 std::string* label) { | |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
198 | |
199 // Create a new request. | |
200 StreamOptions options(false, StreamOptions::kFacingUser); | |
201 DeviceRequest new_request = DeviceRequest(requester, options); | |
202 new_request.type = DeviceRequest::kEnumerateVideoDevices; | |
203 | |
204 StartEnumeration(&new_request, render_process_id, render_view_id, | |
205 security_origin, label); | |
206 } | |
207 | |
208 void MediaStreamManager::OpenVideoDevice( | |
209 MediaStreamRequester* requester, | |
210 int render_process_id, | |
211 int render_view_id, | |
212 const std::string& device_id, | |
213 const std::string& security_origin, | |
214 std::string* label) { | |
215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
216 | |
217 // Create a new request. | |
218 StreamOptions options(false, StreamOptions::kFacingUser); | |
219 DeviceRequest new_request = DeviceRequest(requester, options); | |
220 new_request.type = DeviceRequest::kOpenVideoDevice; | |
221 new_request.requested_device_id = device_id; | |
222 | |
223 StartEnumeration(&new_request, render_process_id, render_view_id, | |
224 security_origin, label); | |
225 } | |
226 | |
227 void MediaStreamManager::StartEnumeration( | |
228 DeviceRequest* new_request, | |
229 int render_process_id, | |
230 int render_view_id, | |
231 const std::string& security_origin, | |
232 std::string* label) { | |
233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
234 | |
235 if (Requested(new_request->options, kAudioCapture)) { | |
236 new_request->state[kAudioCapture] = DeviceRequest::kRequested; | |
237 if (!enumeration_in_progress_[kAudioCapture]) { | |
238 enumeration_in_progress_[kAudioCapture] = true; | |
239 GetDeviceManager(kAudioCapture)->EnumerateDevices(); | |
240 } | |
241 } | |
242 if (Requested(new_request->options, kVideoCapture)) { | |
243 new_request->state[kVideoCapture] = DeviceRequest::kRequested; | |
244 if (!enumeration_in_progress_[kVideoCapture]) { | |
245 enumeration_in_progress_[kVideoCapture] = true; | |
246 GetDeviceManager(kVideoCapture)->EnumerateDevices(); | |
247 } | |
248 } | |
249 | |
250 // Create a label for this request and verify it is unique. | |
251 std::string request_label; | |
252 do { | |
253 request_label = RandomLabel(); | |
254 } while (requests_.find(request_label) != requests_.end()); | |
255 | |
256 requests_.insert(std::make_pair(request_label, *new_request)); | |
257 | |
258 // Get user confirmation to use capture devices. | |
259 // Need to make an asynchronous call to make sure the |requester| gets the | |
260 // |label| before it would receive any event. | |
261 if (new_request->type == DeviceRequest::kGenerateStream) { | |
262 BrowserThread::PostTask(BrowserThread::IO, | |
263 FROM_HERE, | |
264 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | |
265 base::Unretained(device_settings_.get()), | |
266 request_label, render_process_id, | |
267 render_view_id, new_request->options, | |
268 security_origin)); | |
269 } | |
270 | |
271 (*label) = request_label; | |
272 } | |
273 | |
205 void MediaStreamManager::Opened(MediaStreamType stream_type, | 274 void MediaStreamManager::Opened(MediaStreamType stream_type, |
206 int capture_session_id) { | 275 int capture_session_id) { |
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
208 | 277 |
209 // Find the request containing this device and mark it as used. | 278 // Find the request containing this device and mark it as used. |
210 DeviceRequest* request = NULL; | 279 DeviceRequest* request = NULL; |
211 StreamDeviceInfoArray* devices = NULL; | 280 StreamDeviceInfoArray* devices = NULL; |
212 std::string label; | 281 std::string label; |
213 for (DeviceRequests::iterator request_it = requests_.begin(); | 282 for (DeviceRequests::iterator request_it = requests_.begin(); |
214 request_it != requests_.end() && request == NULL; ++request_it) { | 283 request_it != requests_.end() && request == NULL; ++request_it) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 return; | 316 return; |
248 } | 317 } |
249 } | 318 } |
250 request->state[stream_type] = DeviceRequest::kDone; | 319 request->state[stream_type] = DeviceRequest::kDone; |
251 | 320 |
252 if (!RequestDone(*request)) { | 321 if (!RequestDone(*request)) { |
253 // This stream_type is done, but not the other type. | 322 // This stream_type is done, but not the other type. |
254 return; | 323 return; |
255 } | 324 } |
256 | 325 |
257 request->requester->StreamGenerated(label, request->audio_devices, | 326 if (request->type == DeviceRequest::kOpenVideoDevice) { |
258 request->video_devices); | 327 DCHECK_NE(request->options.video_option, StreamOptions::kNoCamera); |
328 request->requester->VideoDeviceOpened(label, request->video_devices[0]); | |
329 } else { | |
mflodman_chromium_OOO
2011/11/29 02:30:56
The else case will include DeviceRequest::kEnumera
wjia(left Chromium)
2011/11/30 00:14:23
Done.
| |
330 request->requester->StreamGenerated(label, request->audio_devices, | |
331 request->video_devices); | |
332 } | |
259 } | 333 } |
260 | 334 |
261 void MediaStreamManager::Closed(MediaStreamType stream_type, | 335 void MediaStreamManager::Closed(MediaStreamType stream_type, |
262 int capture_session_id) { | 336 int capture_session_id) { |
263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
264 } | 338 } |
265 | 339 |
266 void MediaStreamManager::DevicesEnumerated( | 340 void MediaStreamManager::DevicesEnumerated( |
267 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { | 341 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
269 | 343 |
270 // Publish the result for all requests waiting for device list(s). | 344 // Publish the result for all requests waiting for device list(s). |
271 // Find the requests waiting for this device list, store their labels and | 345 // Find the requests waiting for this device list, store their labels and |
272 // release the iterator before calling device settings. We might get a call | 346 // release the iterator before calling device settings. We might get a call |
273 // back from device_settings that will need to iterate through devices. | 347 // back from device_settings that will need to iterate through devices. |
274 std::list<std::string> label_list; | 348 std::list<std::string> label_list; |
275 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 349 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
276 ++it) { | 350 ++it) { |
277 if (it->second.state[stream_type] == DeviceRequest::kRequested && | 351 if (it->second.state[stream_type] == DeviceRequest::kRequested && |
278 Requested(it->second.options, stream_type)) { | 352 Requested(it->second.options, stream_type)) { |
279 label_list.push_back(it->first); | 353 label_list.push_back(it->first); |
280 } | 354 } |
281 } | 355 } |
282 for (std::list<std::string>::iterator it = label_list.begin(); | 356 for (std::list<std::string>::iterator it = label_list.begin(); |
283 it != label_list.end(); ++it) { | 357 it != label_list.end(); ++it) { |
284 device_settings_->AvailableDevices(*it, stream_type, devices); | 358 DeviceRequest& request = requests_[*it]; |
359 if (request.type == DeviceRequest::kEnumerateVideoDevices) { | |
360 DCHECK_NE(request.options.video_option, StreamOptions::kNoCamera); | |
361 request.requester->VideoDevicesEnumerated(*it, devices); | |
362 requests_.erase(*it); | |
363 } else if (request.type == DeviceRequest::kOpenVideoDevice) { | |
364 DCHECK_NE(request.options.video_option, StreamOptions::kNoCamera); | |
365 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | |
366 device_it != devices.end(); device_it++) { | |
367 if (request.requested_device_id == device_it->device_id) { | |
368 StreamDeviceInfo device = *device_it; | |
369 device.in_use = false; | |
370 device.session_id = | |
371 GetDeviceManager(device_it->stream_type)->Open(device); | |
372 request.state[device_it->stream_type] = DeviceRequest::kOpening; | |
373 request.video_devices.push_back(device); | |
374 break; | |
375 } | |
376 } | |
377 } else { | |
378 BrowserThread::PostTask(BrowserThread::IO, | |
379 FROM_HERE, | |
380 base::Bind(&MediaStreamDeviceSettings::AvailableDevices, | |
381 base::Unretained(device_settings_.get()), | |
382 *it, stream_type, devices)); | |
383 } | |
285 } | 384 } |
286 label_list.clear(); | 385 label_list.clear(); |
287 enumeration_in_progress_[stream_type] = false; | 386 enumeration_in_progress_[stream_type] = false; |
288 } | 387 } |
289 | 388 |
290 void MediaStreamManager::Error(MediaStreamType stream_type, | 389 void MediaStreamManager::Error(MediaStreamType stream_type, |
291 int capture_session_id, | 390 int capture_session_id, |
292 MediaStreamProviderError error) { | 391 MediaStreamProviderError error) { |
293 // Find the device for the error call. | 392 // Find the device for the error call. |
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 // 3. Not opened but other devices exists for this request -> remove | 428 // 3. Not opened but other devices exists for this request -> remove |
330 // device from list, but don't signal an error. | 429 // device from list, but don't signal an error. |
331 devices->erase(device_it); | 430 devices->erase(device_it); |
332 } | 431 } |
333 return; | 432 return; |
334 } | 433 } |
335 } | 434 } |
336 } | 435 } |
337 } | 436 } |
338 | 437 |
339 void MediaStreamManager::GetDevices(const std::string& label, | |
340 MediaStreamType stream_type) { | |
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
342 if (!enumeration_in_progress_[stream_type]) { | |
343 enumeration_in_progress_[stream_type] = true; | |
344 GetDeviceManager(stream_type)->EnumerateDevices(); | |
345 } | |
346 } | |
347 | |
348 void MediaStreamManager::DevicesAccepted(const std::string& label, | 438 void MediaStreamManager::DevicesAccepted(const std::string& label, |
349 const StreamDeviceInfoArray& devices) { | 439 const StreamDeviceInfoArray& devices) { |
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
351 DeviceRequests::iterator request_it = requests_.find(label); | 441 DeviceRequests::iterator request_it = requests_.find(label); |
352 if (request_it != requests_.end()) { | 442 if (request_it != requests_.end()) { |
353 if (devices.empty()) { | 443 if (devices.empty()) { |
354 // No available devices or user didn't accept device usage. | 444 // No available devices or user didn't accept device usage. |
355 request_it->second.requester->StreamGenerationFailed(request_it->first); | 445 request_it->second.requester->StreamGenerationFailed(request_it->first); |
356 requests_.erase(request_it); | 446 requests_.erase(request_it); |
357 return; | 447 return; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 } | 479 } |
390 return; | 480 return; |
391 } | 481 } |
392 } | 482 } |
393 | 483 |
394 void MediaStreamManager::SettingsError(const std::string& label) { | 484 void MediaStreamManager::SettingsError(const std::string& label) { |
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
396 // Erase this request and report an error. | 486 // Erase this request and report an error. |
397 DeviceRequests::iterator it = requests_.find(label); | 487 DeviceRequests::iterator it = requests_.find(label); |
398 if (it != requests_.end()) { | 488 if (it != requests_.end()) { |
399 it->second.requester->StreamGenerationFailed(label); | 489 if (it->second.type == DeviceRequest::kEnumerateVideoDevices) { |
490 DCHECK_NE(it->second.options.video_option, StreamOptions::kNoCamera); | |
491 it->second.requester->VideoDevicesEnumerationFailed(label); | |
492 } else if (it->second.type == DeviceRequest::kOpenVideoDevice) { | |
493 DCHECK_NE(it->second.options.video_option, StreamOptions::kNoCamera); | |
494 it->second.requester->VideoDeviceOpenFailed(label); | |
495 } else { | |
496 it->second.requester->StreamGenerationFailed(label); | |
497 } | |
400 requests_.erase(it); | 498 requests_.erase(it); |
401 return; | 499 return; |
402 } | 500 } |
403 } | 501 } |
404 | 502 |
405 void MediaStreamManager::UseFakeDevice() { | 503 void MediaStreamManager::UseFakeDevice() { |
406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
407 video_capture_manager()->UseFakeDevice(); | 505 video_capture_manager()->UseFakeDevice(); |
408 device_settings_->UseFakeUI(); | 506 device_settings_->UseFakeUI(); |
409 } | 507 } |
(...skipping 28 matching lines...) Expand all Loading... | |
438 if (stream_type == kVideoCapture) { | 536 if (stream_type == kVideoCapture) { |
439 return video_capture_manager(); | 537 return video_capture_manager(); |
440 } else if (stream_type == kAudioCapture) { | 538 } else if (stream_type == kAudioCapture) { |
441 return audio_input_device_manager(); | 539 return audio_input_device_manager(); |
442 } | 540 } |
443 NOTREACHED(); | 541 NOTREACHED(); |
444 return NULL; | 542 return NULL; |
445 } | 543 } |
446 | 544 |
447 } // namespace media_stream | 545 } // namespace media_stream |
OLD | NEW |