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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 | 241 |
| 242 return label; | 242 return label; |
| 243 } | 243 } |
| 244 | 244 |
| 245 std::string MediaStreamManager::GenerateStreamForDevice( | 245 std::string MediaStreamManager::GenerateStreamForDevice( |
| 246 MediaStreamRequester* requester, int render_process_id, int render_view_id, | 246 MediaStreamRequester* requester, int render_process_id, int render_view_id, |
| 247 const StreamOptions& options, const std::string& device_id, | 247 const StreamOptions& options, const std::string& device_id, |
| 248 const GURL& security_origin) { | 248 const GURL& security_origin) { |
| 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 250 | 250 |
| 251 int target_render_process_id = -1; | |
| 252 int target_render_view_id = -1; | |
| 253 | |
| 254 // We will post the request to the target render view, not the source (i.e. | |
| 255 // source is an extension, and target is the tab we want to capture). | |
| 256 bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
| 257 device_id, &target_render_process_id, &target_render_view_id); | |
| 258 | |
| 251 // Create a new request based on options. | 259 // Create a new request based on options. |
| 252 DeviceRequest* request = new DeviceRequest(requester, options, | 260 DeviceRequest* request = new DeviceRequest(requester, options, |
| 253 DeviceRequest::GENERATE_STREAM, | 261 DeviceRequest::GENERATE_STREAM, |
| 254 render_process_id, | 262 target_render_process_id, |
| 255 render_view_id, | 263 target_render_view_id, |
| 256 security_origin); | 264 security_origin); |
| 257 const std::string& label = AddRequest(request); | 265 const std::string& label = AddRequest(request); |
| 258 request->requested_device_id = device_id; | 266 request->requested_device_id = device_id; |
| 259 | 267 |
| 260 // Get user confirmation to use the capture device. | 268 if (!has_valid_device_id || |
| 261 PostRequestToUI(label); | 269 !security_origin.SchemeIs(kExtensionScheme) || |
| 262 | |
| 263 if (!security_origin.SchemeIs(kExtensionScheme) || | |
| 264 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && | 270 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
| 265 options.audio_type != MEDIA_NO_SERVICE) || | 271 options.audio_type != MEDIA_NO_SERVICE) || |
| 266 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && | 272 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
| 267 options.video_type != MEDIA_NO_SERVICE)) { | 273 options.video_type != MEDIA_NO_SERVICE)) { |
| 268 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; | 274 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; |
| 275 | |
| 269 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 276 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 270 base::Bind(&MediaStreamManager::CancelRequest, | 277 base::Bind(&MediaStreamManager::CancelRequest, |
| 271 base::Unretained(this), label)); | 278 base::Unretained(this), label)); |
|
wjia(left Chromium)
2012/12/10 05:34:18
In case of error, browser process should send an e
no longer working on chromium
2012/12/10 10:03:19
+1, it seems to me we create a request here and do
| |
| 272 return label; | 279 return label; |
| 273 } | 280 } |
| 274 | 281 |
| 282 // Get user confirmation to use the capture device. | |
| 283 PostRequestToUI(label); | |
| 284 | |
| 275 // TODO(miu): We should ask the device manager whether a device with id | 285 // TODO(miu): We should ask the device manager whether a device with id |
| 276 // |device_id| actually exists. Note that no such MediaStreamProvider API for | 286 // |device_id| actually exists. Note that no such MediaStreamProvider API for |
| 277 // this currently exists. Also, we don't have a user-friendly device name for | 287 // this currently exists. Also, we don't have a user-friendly device name for |
| 278 // the infobar UI. | 288 // the infobar UI. |
| 279 if (IsAudioMediaType(options.audio_type)) { | 289 if (IsAudioMediaType(options.audio_type)) { |
| 280 // TODO(justinlin): Updating the state to requested and pending are no-ops | 290 // TODO(justinlin): Updating the state to requested and pending are no-ops |
| 281 // in terms of the media manager, but these are the state changes we want to | 291 // in terms of the media manager, but these are the state changes we want to |
| 282 // support in terms of extensions (which is registered as an observer). | 292 // support in terms of extensions (which is registered as an observer). |
| 283 request->setState(options.audio_type, MEDIA_REQUEST_STATE_REQUESTED); | 293 request->setState(options.audio_type, MEDIA_REQUEST_STATE_REQUESTED); |
| 284 request->setState(options.audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 294 request->setState(options.audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 unique_label = RandomLabel(); | 586 unique_label = RandomLabel(); |
| 577 } while (requests_.find(unique_label) != requests_.end()); | 587 } while (requests_.find(unique_label) != requests_.end()); |
| 578 | 588 |
| 579 requests_.insert(std::make_pair(unique_label, request)); | 589 requests_.insert(std::make_pair(unique_label, request)); |
| 580 | 590 |
| 581 return unique_label; | 591 return unique_label; |
| 582 } | 592 } |
| 583 | 593 |
| 584 void MediaStreamManager::PostRequestToUI(const std::string& label) { | 594 void MediaStreamManager::PostRequestToUI(const std::string& label) { |
| 585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 587 DeviceRequest* request = requests_[label]; | 596 DeviceRequest* request = requests_[label]; |
| 588 // Get user confirmation to use capture devices. | 597 // Get user confirmation to use capture devices. |
| 589 ui_controller_->MakeUIRequest(label, | 598 ui_controller_->MakeUIRequest(label, |
| 590 request->render_process_id, | 599 request->render_process_id, |
| 591 request->render_view_id, | 600 request->render_view_id, |
| 592 request->options, | 601 request->options, |
| 593 request->security_origin); | 602 request->security_origin); |
| 594 } | 603 } |
| 595 | 604 |
| 596 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { | 605 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 return; | 861 return; |
| 853 } | 862 } |
| 854 | 863 |
| 855 // Process all newly-accepted devices for this request. | 864 // Process all newly-accepted devices for this request. |
| 856 DeviceRequest* request = request_it->second; | 865 DeviceRequest* request = request_it->second; |
| 857 bool found_audio = false, found_video = false; | 866 bool found_audio = false, found_video = false; |
| 858 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 867 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 859 device_it != devices.end(); ++device_it) { | 868 device_it != devices.end(); ++device_it) { |
| 860 StreamDeviceInfo device_info = *device_it; // Make a copy. | 869 StreamDeviceInfo device_info = *device_it; // Make a copy. |
| 861 | 870 |
| 871 // TODO(justinlin): Nicer way to do this? | |
| 872 // Re-append the device_id since we lost it when posting request to UI. | |
| 873 if (device_info.stream_type == content::MEDIA_TAB_VIDEO_CAPTURE || | |
| 874 device_info.stream_type == content::MEDIA_TAB_AUDIO_CAPTURE) | |
| 875 device_info.device_id = request->requested_device_id; | |
| 876 | |
| 862 // Set in_use to false to be able to track if this device has been | 877 // Set in_use to false to be able to track if this device has been |
| 863 // opened. in_use might be true if the device type can be used in more | 878 // opened. in_use might be true if the device type can be used in more |
| 864 // than one session. | 879 // than one session. |
| 865 DCHECK_EQ(request->getState(device_it->stream_type), | 880 DCHECK_EQ(request->getState(device_it->stream_type), |
| 866 MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 881 MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 867 device_info.in_use = false; | 882 device_info.in_use = false; |
| 868 | 883 |
| 869 device_info.session_id = | 884 device_info.session_id = |
| 870 GetDeviceManager(device_info.stream_type)->Open(device_info); | 885 GetDeviceManager(device_info.stream_type)->Open(device_info); |
| 871 request->setState(device_it->stream_type, MEDIA_REQUEST_STATE_OPENING); | 886 request->setState(device_it->stream_type, MEDIA_REQUEST_STATE_OPENING); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 930 ui_controller_.reset(); | 945 ui_controller_.reset(); |
| 931 } | 946 } |
| 932 | 947 |
| 933 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { | 948 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { |
| 934 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 935 MediaStreamDevices opened_devices; | 950 MediaStreamDevices opened_devices; |
| 936 DevicesFromRequest(request, &opened_devices); | 951 DevicesFromRequest(request, &opened_devices); |
| 937 if (opened_devices.empty()) | 952 if (opened_devices.empty()) |
| 938 return; | 953 return; |
| 939 | 954 |
| 940 int target_render_process_id = request.render_process_id; | 955 NotifyUIDevicesOpened(request.render_process_id, |
| 941 int target_render_view_id = request.render_view_id; | 956 request.render_view_id, |
| 942 | |
| 943 // For tab capture requests, we should notify the UI to update the renderer | |
| 944 // that is the target of the capture instead of the requester. | |
| 945 if (request.options.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || | |
| 946 request.options.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
| 947 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
| 948 request.requested_device_id, | |
| 949 &target_render_process_id, | |
| 950 &target_render_view_id)) | |
| 951 return; | |
| 952 } | |
| 953 | |
| 954 NotifyUIDevicesOpened(target_render_process_id, | |
| 955 target_render_view_id, | |
| 956 opened_devices); | 957 opened_devices); |
| 957 } | 958 } |
| 958 | 959 |
| 959 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { | 960 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { |
| 960 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 961 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 961 MediaStreamDevices closed_devices; | 962 MediaStreamDevices closed_devices; |
| 962 DevicesFromRequest(request, &closed_devices); | 963 DevicesFromRequest(request, &closed_devices); |
| 963 if (closed_devices.empty()) | 964 if (closed_devices.empty()) |
| 964 return; | 965 return; |
| 965 | 966 |
| 966 int target_render_process_id = request.render_process_id; | 967 NotifyUIDevicesClosed(request.render_process_id, |
| 967 int target_render_view_id = request.render_view_id; | 968 request.render_view_id, |
| 968 | |
| 969 // For tab capture requests, we should notify the UI to update the renderer | |
| 970 // that is the target of the capture instead of the requester. | |
| 971 if (request.options.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || | |
| 972 request.options.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
| 973 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( | |
| 974 request.requested_device_id, | |
| 975 &target_render_process_id, | |
| 976 &target_render_view_id)) | |
| 977 return; | |
| 978 } | |
| 979 | |
| 980 NotifyUIDevicesClosed(target_render_process_id, | |
| 981 target_render_view_id, | |
| 982 closed_devices); | 969 closed_devices); |
| 983 } | 970 } |
| 984 | 971 |
| 985 void MediaStreamManager::DevicesFromRequest( | 972 void MediaStreamManager::DevicesFromRequest( |
| 986 const DeviceRequest& request, MediaStreamDevices* devices) { | 973 const DeviceRequest& request, MediaStreamDevices* devices) { |
| 987 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 974 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
| 988 it != request.devices.end(); ++it) { | 975 it != request.devices.end(); ++it) { |
| 989 devices->push_back(MediaStreamDevice( | 976 devices->push_back(MediaStreamDevice( |
| 990 it->stream_type, it->device_id, it->name)); | 977 it->stream_type, it->device_id, it->name)); |
| 991 } | 978 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1081 } | 1068 } |
| 1082 | 1069 |
| 1083 // Always do enumeration even though some enumeration is in progress, | 1070 // Always do enumeration even though some enumeration is in progress, |
| 1084 // because those enumeration commands could be sent before these devices | 1071 // because those enumeration commands could be sent before these devices |
| 1085 // change. | 1072 // change. |
| 1086 ++active_enumeration_ref_count_[stream_type]; | 1073 ++active_enumeration_ref_count_[stream_type]; |
| 1087 GetDeviceManager(stream_type)->EnumerateDevices(); | 1074 GetDeviceManager(stream_type)->EnumerateDevices(); |
| 1088 } | 1075 } |
| 1089 | 1076 |
| 1090 } // namespace content | 1077 } // namespace content |
| OLD | NEW |