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 |