OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
172 | 172 |
173 // Create a new request based on options. | 173 // Create a new request based on options. |
174 DeviceRequest new_request(requester, options, | 174 DeviceRequest new_request(requester, options, |
175 render_process_id, | 175 render_process_id, |
176 render_view_id, | 176 render_view_id, |
177 security_origin); | 177 security_origin); |
178 StartEnumeration(&new_request, label); | 178 StartEnumeration(&new_request, label); |
179 } | 179 } |
180 | 180 |
181 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { | |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
183 DeviceRequests::iterator it = requests_.begin(); | |
184 while (it != requests_.end()) { | |
185 if (it->second.requester == requester && !RequestDone(it->second)) { | |
186 // The request isn't complete, but there might be some devices already | |
187 // opened -> close them. | |
188 DeviceRequest* request = &(it->second); | |
189 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | |
190 DeviceRequest::kOpening) { | |
191 for (StreamDeviceInfoArray::iterator it = | |
192 request->audio_devices.begin(); it != request->audio_devices.end(); | |
193 ++it) { | |
194 audio_input_device_manager()->Close(it->session_id); | |
195 } | |
196 } | |
197 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == | |
198 DeviceRequest::kOpening) { | |
199 for (StreamDeviceInfoArray::iterator it = | |
200 request->video_devices.begin(); it != request->video_devices.end(); | |
201 ++it) { | |
202 video_capture_manager()->Close(it->session_id); | |
203 } | |
204 } | |
205 requests_.erase(it++); | |
206 } else { | |
207 ++it; | |
208 } | |
209 } | |
210 } | |
211 | |
212 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 181 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
214 | 183 |
215 DeviceRequests::iterator it = requests_.find(label); | 184 DeviceRequests::iterator it = requests_.find(label); |
216 if (it != requests_.end()) { | 185 if (it != requests_.end()) { |
217 // The request isn't complete. | 186 // The request isn't complete. |
218 if (!RequestDone(it->second)) { | 187 if (!RequestDone(it->second)) { |
219 DeviceRequest* request = &(it->second); | 188 DeviceRequest* request = &(it->second); |
220 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | 189 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == |
221 DeviceRequest::kOpening) { | 190 DeviceRequest::kOpening) { |
(...skipping 27 matching lines...) Expand all Loading... |
249 for (StreamDeviceInfoArray::iterator audio_it = | 218 for (StreamDeviceInfoArray::iterator audio_it = |
250 it->second.audio_devices.begin(); | 219 it->second.audio_devices.begin(); |
251 audio_it != it->second.audio_devices.end(); ++audio_it) { | 220 audio_it != it->second.audio_devices.end(); ++audio_it) { |
252 audio_input_device_manager()->Close(audio_it->session_id); | 221 audio_input_device_manager()->Close(audio_it->session_id); |
253 } | 222 } |
254 for (StreamDeviceInfoArray::iterator video_it = | 223 for (StreamDeviceInfoArray::iterator video_it = |
255 it->second.video_devices.begin(); | 224 it->second.video_devices.begin(); |
256 video_it != it->second.video_devices.end(); ++video_it) { | 225 video_it != it->second.video_devices.end(); ++video_it) { |
257 video_capture_manager()->Close(video_it->session_id); | 226 video_capture_manager()->Close(video_it->session_id); |
258 } | 227 } |
259 if (it->second.type == DeviceRequest::kGenerateStream) { | 228 |
| 229 if (it->second.type == DeviceRequest::kGenerateStream && |
| 230 RequestDone(it->second)) { |
260 NotifyObserverDevicesClosed(&(it->second)); | 231 NotifyObserverDevicesClosed(&(it->second)); |
261 } | 232 } |
262 requests_.erase(it); | 233 requests_.erase(it); |
263 return; | 234 return; |
264 } | 235 } |
265 } | 236 } |
266 | 237 |
267 void MediaStreamManager::EnumerateDevices( | 238 void MediaStreamManager::EnumerateDevices( |
268 MediaStreamRequester* requester, | 239 MediaStreamRequester* requester, |
269 int render_process_id, | 240 int render_process_id, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 311 |
341 // Create a label for this request and verify it is unique. | 312 // Create a label for this request and verify it is unique. |
342 std::string request_label; | 313 std::string request_label; |
343 do { | 314 do { |
344 request_label = RandomLabel(); | 315 request_label = RandomLabel(); |
345 } while (requests_.find(request_label) != requests_.end()); | 316 } while (requests_.find(request_label) != requests_.end()); |
346 | 317 |
347 requests_.insert(std::make_pair(request_label, *new_request)); | 318 requests_.insert(std::make_pair(request_label, *new_request)); |
348 | 319 |
349 // Get user confirmation to use capture devices. | 320 // Get user confirmation to use capture devices. |
350 // Need to make an asynchronous call to make sure the |requester| gets the | |
351 // |label| before it would receive any event. | |
352 if (new_request->type == DeviceRequest::kGenerateStream) { | 321 if (new_request->type == DeviceRequest::kGenerateStream) { |
353 BrowserThread::PostTask(BrowserThread::IO, | 322 device_settings_->RequestCaptureDeviceUsage(request_label, |
354 FROM_HERE, | 323 new_request->render_process_id, |
355 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | 324 new_request->render_view_id, |
356 base::Unretained(device_settings_.get()), | 325 new_request->options, |
357 request_label, new_request->render_process_id, | 326 new_request->security_origin); |
358 new_request->render_view_id, new_request->options, | |
359 new_request->security_origin)); | |
360 } | 327 } |
361 | 328 |
362 (*label) = request_label; | 329 (*label) = request_label; |
363 } | 330 } |
364 | 331 |
365 void MediaStreamManager::EnsureDeviceThreadAndListener() { | 332 void MediaStreamManager::EnsureDeviceThreadAndListener() { |
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
367 if (device_thread_.get()) | 334 if (device_thread_.get()) |
368 return; | 335 return; |
369 | 336 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 request.state[device_it->stream_type] = DeviceRequest::kOpening; | 454 request.state[device_it->stream_type] = DeviceRequest::kOpening; |
488 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 455 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
489 request.audio_devices.push_back(device); | 456 request.audio_devices.push_back(device); |
490 else | 457 else |
491 request.video_devices.push_back(device); | 458 request.video_devices.push_back(device); |
492 break; | 459 break; |
493 } | 460 } |
494 } | 461 } |
495 break; | 462 break; |
496 default: | 463 default: |
497 BrowserThread::PostTask(BrowserThread::IO, | 464 device_settings_->AvailableDevices(*it, stream_type, devices); |
498 FROM_HERE, | |
499 base::Bind(&MediaStreamDeviceSettings::AvailableDevices, | |
500 base::Unretained(device_settings_.get()), | |
501 *it, stream_type, devices)); | |
502 } | 465 } |
503 } | 466 } |
504 label_list.clear(); | 467 label_list.clear(); |
505 enumeration_in_progress_[stream_type] = false; | 468 enumeration_in_progress_[stream_type] = false; |
506 } | 469 } |
507 | 470 |
508 void MediaStreamManager::Error(MediaStreamType stream_type, | 471 void MediaStreamManager::Error(MediaStreamType stream_type, |
509 int capture_session_id, | 472 int capture_session_id, |
510 MediaStreamProviderError error) { | 473 MediaStreamProviderError error) { |
511 // Find the device for the error call. | 474 // Find the device for the error call. |
(...skipping 18 matching lines...) Expand all Loading... |
530 // 1. Already opened -> signal device failure and close device. | 493 // 1. Already opened -> signal device failure and close device. |
531 // Use device_idx to signal which of the devices encountered an | 494 // Use device_idx to signal which of the devices encountered an |
532 // error. | 495 // error. |
533 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 496 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
534 it->second.requester->AudioDeviceFailed(it->first, device_idx); | 497 it->second.requester->AudioDeviceFailed(it->first, device_idx); |
535 } else if (stream_type == | 498 } else if (stream_type == |
536 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 499 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
537 it->second.requester->VideoDeviceFailed(it->first, device_idx); | 500 it->second.requester->VideoDeviceFailed(it->first, device_idx); |
538 } | 501 } |
539 GetDeviceManager(stream_type)->Close(capture_session_id); | 502 GetDeviceManager(stream_type)->Close(capture_session_id); |
540 devices->erase(device_it); | 503 // We don't erase the devices here so that we can update the UI |
541 } else if (it->second.audio_devices.size() | 504 // properly in StopGeneratedStream(). |
542 + it->second.video_devices.size() <= 1) { | 505 it->second.state[stream_type] = DeviceRequest::kError; |
543 // 2. Device not opened and no other devices for this request -> | |
544 // signal stream error and remove the request. | |
545 it->second.requester->StreamGenerationFailed(it->first); | |
546 requests_.erase(it); | |
547 } else { | 506 } else { |
548 // 3. Not opened but other devices exists for this request -> remove | 507 // Request is not done, devices are not opened in this case. |
549 // device from list, but don't signal an error. | 508 if (it->second.audio_devices.size() |
550 devices->erase(device_it); | 509 + it->second.video_devices.size() <= 1) { |
| 510 // 2. Device not opened and no other devices for this request -> |
| 511 // signal stream error and remove the request. |
| 512 it->second.requester->StreamGenerationFailed(it->first); |
| 513 requests_.erase(it); |
| 514 } else { |
| 515 // 3. Not opened but other devices exists for this request -> remove |
| 516 // device from list, but don't signal an error. |
| 517 devices->erase(device_it); |
| 518 } |
551 } | 519 } |
552 return; | 520 return; |
553 } | 521 } |
554 } | 522 } |
555 } | 523 } |
556 } | 524 } |
557 | 525 |
558 void MediaStreamManager::DevicesAccepted(const std::string& label, | 526 void MediaStreamManager::DevicesAccepted(const std::string& label, |
559 const StreamDeviceInfoArray& devices) { | 527 const StreamDeviceInfoArray& devices) { |
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 content::MediaStreamDevice( | 647 content::MediaStreamDevice( |
680 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 648 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, |
681 it->device_id, | 649 it->device_id, |
682 it->name)); | 650 it->name)); |
683 } | 651 } |
684 } | 652 } |
685 | 653 |
686 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 654 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
688 // Check if all devices are opened. | 656 // Check if all devices are opened. |
689 if (Requested(request.options, | 657 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
690 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { | 658 if (Requested(request.options, stream_type)) { |
| 659 if (request.state[stream_type] != DeviceRequest::kDone && |
| 660 request.state[stream_type] != DeviceRequest::kError) |
| 661 return false; |
| 662 |
691 for (StreamDeviceInfoArray::const_iterator it = | 663 for (StreamDeviceInfoArray::const_iterator it = |
692 request.audio_devices.begin(); it != request.audio_devices.end(); | 664 request.audio_devices.begin(); it != request.audio_devices.end(); |
693 ++it) { | 665 ++it) { |
694 if (it->in_use == false) { | 666 if (it->in_use == false) { |
695 return false; | 667 return false; |
696 } | 668 } |
697 } | 669 } |
698 } | 670 } |
699 if (Requested(request.options, | 671 |
700 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE)) { | 672 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
| 673 if (Requested(request.options, stream_type)) { |
| 674 if (request.state[stream_type] != DeviceRequest::kDone && |
| 675 request.state[stream_type] != DeviceRequest::kError) |
| 676 return false; |
| 677 |
701 for (StreamDeviceInfoArray::const_iterator it = | 678 for (StreamDeviceInfoArray::const_iterator it = |
702 request.video_devices.begin(); it != request.video_devices.end(); | 679 request.video_devices.begin(); it != request.video_devices.end(); |
703 ++it) { | 680 ++it) { |
704 if (it->in_use == false) { | 681 if (it->in_use == false) { |
705 return false; | 682 return false; |
706 } | 683 } |
707 } | 684 } |
708 } | 685 } |
| 686 |
709 return true; | 687 return true; |
710 } | 688 } |
711 | 689 |
712 // Called to get media capture device manager of specified type. | 690 // Called to get media capture device manager of specified type. |
713 MediaStreamProvider* MediaStreamManager::GetDeviceManager( | 691 MediaStreamProvider* MediaStreamManager::GetDeviceManager( |
714 MediaStreamType stream_type) { | 692 MediaStreamType stream_type) { |
715 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 693 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
716 return video_capture_manager(); | 694 return video_capture_manager(); |
717 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 695 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
718 return audio_input_device_manager(); | 696 return audio_input_device_manager(); |
719 } | 697 } |
720 NOTREACHED(); | 698 NOTREACHED(); |
721 return NULL; | 699 return NULL; |
722 } | 700 } |
723 | 701 |
724 } // namespace media_stream | 702 } // namespace media_stream |
OLD | NEW |