Chromium Code Reviews| 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/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 | 238 |
| 239 return label; | 239 return label; |
| 240 } | 240 } |
| 241 | 241 |
| 242 std::string MediaStreamManager::GenerateStreamForDevice( | 242 std::string MediaStreamManager::GenerateStreamForDevice( |
| 243 MediaStreamRequester* requester, int render_process_id, int render_view_id, | 243 MediaStreamRequester* requester, int render_process_id, int render_view_id, |
| 244 const StreamOptions& options, const std::string& device_id, | 244 const StreamOptions& options, const std::string& device_id, |
| 245 const GURL& security_origin) { | 245 const GURL& security_origin) { |
| 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 247 | 247 |
| 248 int target_render_process_id = -1; | |
| 249 int target_render_view_id = -1; | |
| 250 // We will post the request to the target render view, not the source (i.e. | |
| 251 // source is an extension, and target is the tab we want to capture). | |
| 252 DCHECK(WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
|
no longer working on chromium
2012/12/05 17:38:37
If you put it in DCHECK, the code won't run in rel
| |
| 253 device_id, &target_render_process_id, &target_render_view_id)); | |
| 254 DCHECK_NE(target_render_process_id, -1); | |
| 255 DCHECK_NE(target_render_view_id, -1); | |
| 256 | |
| 248 // Create a new request based on options. | 257 // Create a new request based on options. |
| 249 DeviceRequest* request = new DeviceRequest(requester, options, | 258 DeviceRequest* request = new DeviceRequest(requester, options, |
| 250 DeviceRequest::GENERATE_STREAM, | 259 DeviceRequest::GENERATE_STREAM, |
| 251 render_process_id, | 260 target_render_process_id, |
| 252 render_view_id, | 261 target_render_view_id, |
| 253 security_origin); | 262 security_origin); |
| 254 const std::string& label = AddRequest(request); | 263 const std::string& label = AddRequest(request); |
| 255 request->requested_device_id = device_id; | 264 request->requested_device_id = device_id; |
| 256 | 265 |
| 257 if (!security_origin.SchemeIs(kExtensionScheme) || | 266 if (!security_origin.SchemeIs(kExtensionScheme) || |
| 258 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && | 267 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
| 259 options.audio_type != MEDIA_NO_SERVICE) || | 268 options.audio_type != MEDIA_NO_SERVICE) || |
| 260 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && | 269 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
| 261 options.video_type != MEDIA_NO_SERVICE)) { | 270 options.video_type != MEDIA_NO_SERVICE)) { |
| 262 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; | 271 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 275 // in terms of the media manager, but these are the state changes we want to | 284 // in terms of the media manager, but these are the state changes we want to |
| 276 // support in terms of extensions (which is registered as an observer). | 285 // support in terms of extensions (which is registered as an observer). |
| 277 request->setState(options.audio_type, MEDIA_REQUEST_STATE_REQUESTED); | 286 request->setState(options.audio_type, MEDIA_REQUEST_STATE_REQUESTED); |
| 278 request->setState(options.audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 287 request->setState(options.audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 279 } | 288 } |
| 280 if (IsVideoMediaType(options.video_type)) { | 289 if (IsVideoMediaType(options.video_type)) { |
| 281 request->setState(options.video_type, MEDIA_REQUEST_STATE_REQUESTED); | 290 request->setState(options.video_type, MEDIA_REQUEST_STATE_REQUESTED); |
| 282 request->setState(options.video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 291 request->setState(options.video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 283 } | 292 } |
| 284 | 293 |
| 285 // TODO(xians): Figure out the way to handle tab capture request. | |
| 286 // Can we verify the devices here before sending the request to UI? | |
| 287 HandleRequest(label); | 294 HandleRequest(label); |
| 288 | 295 |
| 289 return label; | 296 return label; |
| 290 } | 297 } |
| 291 | 298 |
| 292 void MediaStreamManager::CancelRequest(const std::string& label) { | 299 void MediaStreamManager::CancelRequest(const std::string& label) { |
| 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 294 | 301 |
| 295 DeviceRequests::iterator it = requests_.find(label); | 302 DeviceRequests::iterator it = requests_.find(label); |
| 296 if (it != requests_.end()) { | 303 if (it != requests_.end()) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 ui_controller_->MakeUIRequest(label, | 585 ui_controller_->MakeUIRequest(label, |
| 579 request->render_process_id, | 586 request->render_process_id, |
| 580 request->render_view_id, | 587 request->render_view_id, |
| 581 request->options, | 588 request->options, |
| 582 request->security_origin); | 589 request->security_origin); |
| 583 } | 590 } |
| 584 | 591 |
| 585 void MediaStreamManager::HandleRequest(const std::string& label) { | 592 void MediaStreamManager::HandleRequest(const std::string& label) { |
| 586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 587 DeviceRequest* request = requests_[label]; | 594 DeviceRequest* request = requests_[label]; |
| 588 if ((IsAudioMediaType(request->options.audio_type) && | 595 // We want to always post request to UI for tab capture to verify the request. |
| 589 !audio_enumeration_cache_.valid) || | 596 if ((request->options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
| 590 (IsVideoMediaType(request->options.video_type) && | 597 request->options.video_type != MEDIA_TAB_VIDEO_CAPTURE) && |
| 591 !video_enumeration_cache_.valid)) { | 598 ((IsAudioMediaType(request->options.audio_type) && |
| 599 !audio_enumeration_cache_.valid) || | |
| 600 (IsVideoMediaType(request->options.video_type) && | |
| 601 !video_enumeration_cache_.valid))) { | |
| 592 // Enumerate the devices if there is no valid device lists to be used. | 602 // Enumerate the devices if there is no valid device lists to be used. |
| 593 StartEnumeration(request); | 603 StartEnumeration(request); |
| 594 } else { | 604 } else { |
| 595 // No need to do new device enumerations, post the request to UI | 605 // No need to do new device enumerations, post the request to UI |
| 596 // immediately. | 606 // immediately. |
| 597 if (IsAudioMediaType(request->options.audio_type)) { | 607 if (IsAudioMediaType(request->options.audio_type)) { |
| 598 request->setState(request->options.audio_type, | 608 request->setState(request->options.audio_type, |
| 599 MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 609 MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 600 } | 610 } |
| 601 if (IsVideoMediaType(request->options.video_type)) { | 611 if (IsVideoMediaType(request->options.video_type)) { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 } | 855 } |
| 846 return; | 856 return; |
| 847 } | 857 } |
| 848 } | 858 } |
| 849 } | 859 } |
| 850 | 860 |
| 851 void MediaStreamManager::DevicesAccepted(const std::string& label, | 861 void MediaStreamManager::DevicesAccepted(const std::string& label, |
| 852 const StreamDeviceInfoArray& devices) { | 862 const StreamDeviceInfoArray& devices) { |
| 853 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 854 DCHECK(!devices.empty()); | 864 DCHECK(!devices.empty()); |
| 865 | |
| 855 DeviceRequests::iterator request_it = requests_.find(label); | 866 DeviceRequests::iterator request_it = requests_.find(label); |
| 856 if (request_it == requests_.end()) { | 867 if (request_it == requests_.end()) { |
| 857 return; | 868 return; |
| 858 } | 869 } |
| 859 | 870 |
| 860 if (request_it->second->type == DeviceRequest::DEVICE_ACCESS) { | 871 if (request_it->second->type == DeviceRequest::DEVICE_ACCESS) { |
| 861 scoped_ptr<DeviceRequest> request(request_it->second); | 872 scoped_ptr<DeviceRequest> request(request_it->second); |
| 862 if (!request->callback.is_null()) { | 873 if (!request->callback.is_null()) { |
| 863 // Map the devices to MediaStreamDevices. | 874 // Map the devices to MediaStreamDevices. |
| 864 MediaStreamDevices selected_devices; | 875 MediaStreamDevices selected_devices; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 876 return; | 887 return; |
| 877 } | 888 } |
| 878 | 889 |
| 879 // Process all newly-accepted devices for this request. | 890 // Process all newly-accepted devices for this request. |
| 880 DeviceRequest* request = request_it->second; | 891 DeviceRequest* request = request_it->second; |
| 881 bool found_audio = false, found_video = false; | 892 bool found_audio = false, found_video = false; |
| 882 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 893 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 883 device_it != devices.end(); ++device_it) { | 894 device_it != devices.end(); ++device_it) { |
| 884 StreamDeviceInfo device_info = *device_it; // Make a copy. | 895 StreamDeviceInfo device_info = *device_it; // Make a copy. |
| 885 | 896 |
| 897 // TODO(justinlin): Nicer way to do this? | |
| 898 // Re-append the device_id since we lost it when posting request to UI. | |
| 899 if (device_info.stream_type == content::MEDIA_TAB_VIDEO_CAPTURE || | |
| 900 device_info.stream_type == content::MEDIA_TAB_AUDIO_CAPTURE) | |
| 901 device_info.device_id = request->requested_device_id; | |
| 902 | |
| 886 // Set in_use to false to be able to track if this device has been | 903 // Set in_use to false to be able to track if this device has been |
| 887 // opened. in_use might be true if the device type can be used in more | 904 // opened. in_use might be true if the device type can be used in more |
| 888 // than one session. | 905 // than one session. |
| 889 DCHECK_EQ(request->getState(device_it->stream_type), | 906 DCHECK_EQ(request->getState(device_it->stream_type), |
| 890 MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 907 MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 891 device_info.in_use = false; | 908 device_info.in_use = false; |
| 892 | 909 |
| 893 device_info.session_id = | 910 device_info.session_id = |
| 894 GetDeviceManager(device_info.stream_type)->Open(device_info); | 911 GetDeviceManager(device_info.stream_type)->Open(device_info); |
| 895 request->setState(device_it->stream_type, MEDIA_REQUEST_STATE_OPENING); | 912 request->setState(device_it->stream_type, MEDIA_REQUEST_STATE_OPENING); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 980 ui_controller_.reset(); | 997 ui_controller_.reset(); |
| 981 } | 998 } |
| 982 | 999 |
| 983 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { | 1000 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { |
| 984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 985 MediaStreamDevices opened_devices; | 1002 MediaStreamDevices opened_devices; |
| 986 DevicesFromRequest(request, &opened_devices); | 1003 DevicesFromRequest(request, &opened_devices); |
| 987 if (opened_devices.empty()) | 1004 if (opened_devices.empty()) |
| 988 return; | 1005 return; |
| 989 | 1006 |
| 990 int target_render_process_id = request.render_process_id; | 1007 NotifyUIDevicesOpened(request.render_process_id, |
| 991 int target_render_view_id = request.render_view_id; | 1008 request.render_view_id, |
| 992 | |
| 993 // For tab capture requests, we should notify the UI to update the renderer | |
| 994 // that is the target of the capture instead of the requester. | |
| 995 if (request.options.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || | |
| 996 request.options.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
| 997 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
| 998 request.requested_device_id, | |
| 999 &target_render_process_id, | |
| 1000 &target_render_view_id)) | |
| 1001 return; | |
| 1002 } | |
| 1003 | |
| 1004 NotifyUIDevicesOpened(target_render_process_id, | |
| 1005 target_render_view_id, | |
| 1006 opened_devices); | 1009 opened_devices); |
| 1007 } | 1010 } |
| 1008 | 1011 |
| 1009 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { | 1012 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { |
| 1010 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1011 MediaStreamDevices closed_devices; | 1014 MediaStreamDevices closed_devices; |
| 1012 DevicesFromRequest(request, &closed_devices); | 1015 DevicesFromRequest(request, &closed_devices); |
| 1013 if (closed_devices.empty()) | 1016 if (closed_devices.empty()) |
| 1014 return; | 1017 return; |
| 1015 | 1018 |
| 1016 int target_render_process_id = request.render_process_id; | 1019 NotifyUIDevicesClosed(request.render_process_id, |
| 1017 int target_render_view_id = request.render_view_id; | 1020 request.render_view_id, |
| 1018 | |
| 1019 // For tab capture requests, we should notify the UI to update the renderer | |
| 1020 // that is the target of the capture instead of the requester. | |
| 1021 if (request.options.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || | |
| 1022 request.options.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
| 1023 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
| 1024 request.requested_device_id, | |
| 1025 &target_render_process_id, | |
| 1026 &target_render_view_id)) | |
| 1027 return; | |
| 1028 } | |
| 1029 | |
| 1030 NotifyUIDevicesClosed(target_render_process_id, | |
| 1031 target_render_view_id, | |
| 1032 closed_devices); | 1021 closed_devices); |
| 1033 } | 1022 } |
| 1034 | 1023 |
| 1035 void MediaStreamManager::DevicesFromRequest( | 1024 void MediaStreamManager::DevicesFromRequest( |
| 1036 const DeviceRequest& request, MediaStreamDevices* devices) { | 1025 const DeviceRequest& request, MediaStreamDevices* devices) { |
| 1037 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 1026 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
| 1038 it != request.devices.end(); ++it) { | 1027 it != request.devices.end(); ++it) { |
| 1039 devices->push_back(MediaStreamDevice( | 1028 devices->push_back(MediaStreamDevice( |
| 1040 it->stream_type, it->device_id, it->name)); | 1029 it->stream_type, it->device_id, it->name)); |
| 1041 } | 1030 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 } | 1120 } |
| 1132 | 1121 |
| 1133 // Always do enumeration even though some enumeration is in progress, | 1122 // Always do enumeration even though some enumeration is in progress, |
| 1134 // because those enumeration commands could be sent before these devices | 1123 // because those enumeration commands could be sent before these devices |
| 1135 // change. | 1124 // change. |
| 1136 ++active_enumeration_ref_count_[stream_type]; | 1125 ++active_enumeration_ref_count_[stream_type]; |
| 1137 GetDeviceManager(stream_type)->EnumerateDevices(); | 1126 GetDeviceManager(stream_type)->EnumerateDevices(); |
| 1138 } | 1127 } |
| 1139 | 1128 |
| 1140 } // namespace content | 1129 } // namespace content |
| OLD | NEW |