| 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 177 | 177 |
| 178 // Create a new request based on options. | 178 // Create a new request based on options. |
| 179 DeviceRequest new_request(requester, options, | 179 DeviceRequest new_request(requester, options, |
| 180 render_process_id, | 180 render_process_id, |
| 181 render_view_id, | 181 render_view_id, |
| 182 security_origin); | 182 security_origin); |
| 183 StartEnumeration(&new_request, label); | 183 StartEnumeration(&new_request, label); |
| 184 | 184 |
| 185 // Get user confirmation to use capture devices. | 185 // Get user confirmation to use capture devices. |
| 186 // Need to make an asynchronous call to make sure the |requester| gets the | 186 device_settings_->RequestCaptureDeviceUsage(*label, |
| 187 // |label| before it would receive any event. | 187 render_process_id, |
| 188 BrowserThread::PostTask(BrowserThread::IO, | 188 render_view_id, |
| 189 FROM_HERE, | 189 options, |
| 190 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | 190 security_origin); |
| 191 base::Unretained(device_settings_.get()), | |
| 192 *label, render_process_id, | |
| 193 render_view_id, options, | |
| 194 security_origin)); | |
| 195 } | |
| 196 | |
| 197 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { | |
| 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 199 DeviceRequests::iterator it = requests_.begin(); | |
| 200 while (it != requests_.end()) { | |
| 201 if (it->second.requester == requester && !RequestDone(it->second)) { | |
| 202 // The request isn't complete, but there might be some devices already | |
| 203 // opened -> close them. | |
| 204 DeviceRequest* request = &(it->second); | |
| 205 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | |
| 206 DeviceRequest::STATE_OPENING) { | |
| 207 for (StreamDeviceInfoArray::iterator it = | |
| 208 request->audio_devices.begin(); it != request->audio_devices.end(); | |
| 209 ++it) { | |
| 210 audio_input_device_manager()->Close(it->session_id); | |
| 211 } | |
| 212 } | |
| 213 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == | |
| 214 DeviceRequest::STATE_OPENING) { | |
| 215 for (StreamDeviceInfoArray::iterator it = | |
| 216 request->video_devices.begin(); it != request->video_devices.end(); | |
| 217 ++it) { | |
| 218 video_capture_manager()->Close(it->session_id); | |
| 219 } | |
| 220 } | |
| 221 requests_.erase(it++); | |
| 222 } else { | |
| 223 ++it; | |
| 224 } | |
| 225 } | |
| 226 } | 191 } |
| 227 | 192 |
| 228 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 193 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
| 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 230 | 195 |
| 231 DeviceRequests::iterator it = requests_.find(label); | 196 DeviceRequests::iterator it = requests_.find(label); |
| 232 if (it != requests_.end()) { | 197 if (it != requests_.end()) { |
| 233 // The request isn't complete. | 198 // The request isn't complete. |
| 234 if (!RequestDone(it->second)) { | 199 if (!RequestDone(it->second)) { |
| 235 DeviceRequest* request = &(it->second); | 200 DeviceRequest* request = &(it->second); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 for (StreamDeviceInfoArray::iterator audio_it = | 234 for (StreamDeviceInfoArray::iterator audio_it = |
| 270 it->second.audio_devices.begin(); | 235 it->second.audio_devices.begin(); |
| 271 audio_it != it->second.audio_devices.end(); ++audio_it) { | 236 audio_it != it->second.audio_devices.end(); ++audio_it) { |
| 272 audio_input_device_manager()->Close(audio_it->session_id); | 237 audio_input_device_manager()->Close(audio_it->session_id); |
| 273 } | 238 } |
| 274 for (StreamDeviceInfoArray::iterator video_it = | 239 for (StreamDeviceInfoArray::iterator video_it = |
| 275 it->second.video_devices.begin(); | 240 it->second.video_devices.begin(); |
| 276 video_it != it->second.video_devices.end(); ++video_it) { | 241 video_it != it->second.video_devices.end(); ++video_it) { |
| 277 video_capture_manager()->Close(video_it->session_id); | 242 video_capture_manager()->Close(video_it->session_id); |
| 278 } | 243 } |
| 279 if (it->second.type == DeviceRequest::GENERATE_STREAM) { | 244 if (it->second.type == DeviceRequest::GENERATE_STREAM && |
| 245 RequestDone(it->second)) { |
| 280 NotifyObserverDevicesClosed(&(it->second)); | 246 NotifyObserverDevicesClosed(&(it->second)); |
| 281 } | 247 } |
| 282 requests_.erase(it); | 248 requests_.erase(it); |
| 283 } | 249 } |
| 284 } | 250 } |
| 285 | 251 |
| 286 void MediaStreamManager::EnumerateDevices( | 252 void MediaStreamManager::EnumerateDevices( |
| 287 MediaStreamRequester* requester, | 253 MediaStreamRequester* requester, |
| 288 int render_process_id, | 254 int render_process_id, |
| 289 int render_view_id, | 255 int render_view_id, |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 DeviceRequest::STATE_OPENING; | 554 DeviceRequest::STATE_OPENING; |
| 589 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
| 590 request.audio_devices.push_back(device); | 556 request.audio_devices.push_back(device); |
| 591 else | 557 else |
| 592 request.video_devices.push_back(device); | 558 request.video_devices.push_back(device); |
| 593 break; | 559 break; |
| 594 } | 560 } |
| 595 } | 561 } |
| 596 break; | 562 break; |
| 597 default: | 563 default: |
| 598 BrowserThread::PostTask(BrowserThread::IO, | 564 device_settings_->AvailableDevices(*it, stream_type, devices); |
| 599 FROM_HERE, | |
| 600 base::Bind(&MediaStreamDeviceSettings::AvailableDevices, | |
| 601 base::Unretained(device_settings_.get()), | |
| 602 *it, stream_type, devices)); | |
| 603 } | 565 } |
| 604 } | 566 } |
| 605 label_list.clear(); | 567 label_list.clear(); |
| 606 --active_enumeration_ref_count_[stream_type]; | 568 --active_enumeration_ref_count_[stream_type]; |
| 607 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| 608 } | 570 } |
| 609 | 571 |
| 610 void MediaStreamManager::Error(MediaStreamType stream_type, | 572 void MediaStreamManager::Error(MediaStreamType stream_type, |
| 611 int capture_session_id, | 573 int capture_session_id, |
| 612 MediaStreamProviderError error) { | 574 MediaStreamProviderError error) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 632 // 1. Already opened -> signal device failure and close device. | 594 // 1. Already opened -> signal device failure and close device. |
| 633 // Use device_idx to signal which of the devices encountered an | 595 // Use device_idx to signal which of the devices encountered an |
| 634 // error. | 596 // error. |
| 635 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
| 636 it->second.requester->AudioDeviceFailed(it->first, device_idx); | 598 it->second.requester->AudioDeviceFailed(it->first, device_idx); |
| 637 } else if (stream_type == | 599 } else if (stream_type == |
| 638 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
| 639 it->second.requester->VideoDeviceFailed(it->first, device_idx); | 601 it->second.requester->VideoDeviceFailed(it->first, device_idx); |
| 640 } | 602 } |
| 641 GetDeviceManager(stream_type)->Close(capture_session_id); | 603 GetDeviceManager(stream_type)->Close(capture_session_id); |
| 642 devices->erase(device_it); | 604 // We don't erase the devices here so that we can update the UI |
| 643 } else if (it->second.audio_devices.size() | 605 // properly in StopGeneratedStream(). |
| 644 + it->second.video_devices.size() <= 1) { | 606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; |
| 645 // 2. Device not opened and no other devices for this request -> | |
| 646 // signal stream error and remove the request. | |
| 647 it->second.requester->StreamGenerationFailed(it->first); | |
| 648 requests_.erase(it); | |
| 649 } else { | 607 } else { |
| 650 // 3. Not opened but other devices exists for this request -> remove | 608 // Request is not done, devices are not opened in this case. |
| 651 // device from list, but don't signal an error. | 609 if ((it->second.audio_devices.size() + |
| 652 devices->erase(device_it); | 610 it->second.video_devices.size()) <= 1) { |
| 611 // 2. Device not opened and no other devices for this request -> |
| 612 // signal stream error and remove the request. |
| 613 it->second.requester->StreamGenerationFailed(it->first); |
| 614 requests_.erase(it); |
| 615 } else { |
| 616 // 3. Not opened but other devices exists for this request -> remove |
| 617 // device from list, but don't signal an error. |
| 618 devices->erase(device_it); |
| 619 } |
| 653 } | 620 } |
| 654 return; | 621 return; |
| 655 } | 622 } |
| 656 } | 623 } |
| 657 } | 624 } |
| 658 } | 625 } |
| 659 | 626 |
| 660 void MediaStreamManager::DevicesAccepted(const std::string& label, | 627 void MediaStreamManager::DevicesAccepted(const std::string& label, |
| 661 const StreamDeviceInfoArray& devices) { | 628 const StreamDeviceInfoArray& devices) { |
| 662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 content::MediaStreamDevice( | 751 content::MediaStreamDevice( |
| 785 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 752 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, |
| 786 it->device_id, | 753 it->device_id, |
| 787 it->name)); | 754 it->name)); |
| 788 } | 755 } |
| 789 } | 756 } |
| 790 | 757 |
| 791 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
| 792 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 793 // Check if all devices are opened. | 760 // Check if all devices are opened. |
| 794 if (Requested(request.options, | 761 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
| 795 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { | 762 if (Requested(request.options, stream_type)) { |
| 763 if (request.state[stream_type] != DeviceRequest::STATE_DONE && |
| 764 request.state[stream_type] != DeviceRequest::STATE_ERROR) { |
| 765 return false; |
| 766 } |
| 767 |
| 796 for (StreamDeviceInfoArray::const_iterator it = | 768 for (StreamDeviceInfoArray::const_iterator it = |
| 797 request.audio_devices.begin(); it != request.audio_devices.end(); | 769 request.audio_devices.begin(); it != request.audio_devices.end(); |
| 798 ++it) { | 770 ++it) { |
| 799 if (it->in_use == false) { | 771 if (it->in_use == false) { |
| 800 return false; | 772 return false; |
| 801 } | 773 } |
| 802 } | 774 } |
| 803 } | 775 } |
| 804 if (Requested(request.options, | 776 |
| 805 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE)) { | 777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
| 778 if (Requested(request.options, stream_type)) { |
| 779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && |
| 780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { |
| 781 return false; |
| 782 } |
| 783 |
| 806 for (StreamDeviceInfoArray::const_iterator it = | 784 for (StreamDeviceInfoArray::const_iterator it = |
| 807 request.video_devices.begin(); it != request.video_devices.end(); | 785 request.video_devices.begin(); it != request.video_devices.end(); |
| 808 ++it) { | 786 ++it) { |
| 809 if (it->in_use == false) { | 787 if (it->in_use == false) { |
| 810 return false; | 788 return false; |
| 811 } | 789 } |
| 812 } | 790 } |
| 813 } | 791 } |
| 792 |
| 814 return true; | 793 return true; |
| 815 } | 794 } |
| 816 | 795 |
| 817 // Called to get media capture device manager of specified type. | 796 // Called to get media capture device manager of specified type. |
| 818 MediaStreamProvider* MediaStreamManager::GetDeviceManager( | 797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( |
| 819 MediaStreamType stream_type) { | 798 MediaStreamType stream_type) { |
| 820 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
| 821 return video_capture_manager(); | 800 return video_capture_manager(); |
| 822 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
| 823 return audio_input_device_manager(); | 802 return audio_input_device_manager(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 it != requests_.end(); ++it) { | 852 it != requests_.end(); ++it) { |
| 874 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | 853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
| 875 Requested(it->second.options, stream_type)) { | 854 Requested(it->second.options, stream_type)) { |
| 876 return true; | 855 return true; |
| 877 } | 856 } |
| 878 } | 857 } |
| 879 return false; | 858 return false; |
| 880 } | 859 } |
| 881 | 860 |
| 882 } // namespace media_stream | 861 } // namespace media_stream |
| OLD | NEW |