Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_manager.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc |
| index 96fc5a10b2edcf228aacc628c3cc887dcf7a4b3c..e804854f8a8a6eeb2917d3198239427bdcedd655 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -518,7 +518,7 @@ void VideoCaptureManager::OnDeviceStarted( |
| int serial_id, |
| std::unique_ptr<VideoCaptureDevice> device) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - DCHECK(serial_id == device_start_queue_.begin()->serial_id()); |
| + DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
| DVLOG(3) << "OnDeviceStarted"; |
|
emircan
2016/08/03 21:55:54
__func__
mcasas
2016/08/03 22:19:36
Done.
|
| if (device_start_queue_.front().abort_start()) { |
| // |device| can be null if creation failed in |
| @@ -545,6 +545,15 @@ void VideoCaptureManager::OnDeviceStarted( |
| DCHECK(session_id != kFakeSessionId); |
| MaybePostDesktopCaptureWindowId(session_id); |
| } |
| + |
| + auto request = photo_request_queue_.begin(); |
| + while(request != photo_request_queue_.end()) { |
| + if (GetDeviceEntryBySessionId(request->first)->video_capture_device()) { |
| + request->second.Run(entry->video_capture_device()); |
| + photo_request_queue_.erase(request); |
| + } |
| + ++request; |
| + } |
| } |
| device_start_queue_.pop_front(); |
| @@ -863,15 +872,19 @@ void VideoCaptureManager::GetPhotoCapabilities( |
| int session_id, |
| VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| - if (!device) |
| + |
| + const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + if (!entry) |
| return; |
| - // Unretained(device) is safe to use here because |device| would be null if it |
| - // was scheduled for shutdown and destruction, and because this task is |
| - // guaranteed to run before the task that destroys the |device|. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities, |
| - base::Unretained(device), base::Passed(&callback))); |
| + VideoCaptureDevice* device = entry->video_capture_device(); |
| + if (device) { |
| + VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device); |
| + return; |
| + } |
| + // |entry| is known but |device| is nullptr, queue up a request for later. |
| + photo_request_queue_.emplace_back( |
| + session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, |
| + base::Passed(&callback))); |
| } |
| void VideoCaptureManager::SetPhotoOptions( |
| @@ -879,28 +892,39 @@ void VideoCaptureManager::SetPhotoOptions( |
| media::mojom::PhotoSettingsPtr settings, |
| VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| - if (!device) |
| + |
| + const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + if (!entry) |
| return; |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device), |
| - base::Passed(&settings), base::Passed(&callback))); |
| + VideoCaptureDevice* device = entry->video_capture_device(); |
| + if (device) { |
| + VideoCaptureManager::DoSetPhotoOptions(std::move(callback), |
| + std::move(settings), device); |
| + return; |
| + } |
| + // |entry| is known but |device| is nullptr, queue up a request for later. |
| + photo_request_queue_.emplace_back( |
| + session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this, |
| + base::Passed(&callback), base::Passed(&settings))); |
| } |
| void VideoCaptureManager::TakePhoto( |
| int session_id, |
| VideoCaptureDevice::TakePhotoCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| - if (!device) |
| + |
| + const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + if (!entry) |
| return; |
| - // Unretained(device) is safe to use here because |device| would be null if it |
| - // was scheduled for shutdown and destruction, and because this task is |
| - // guaranteed to run before the task that destroys the |device|. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto, |
| - base::Unretained(device), base::Passed(&callback))); |
| + VideoCaptureDevice* device = entry->video_capture_device(); |
| + if (device) { |
| + VideoCaptureManager::DoTakePhoto(std::move(callback), device); |
| + return; |
| + } |
| + // |entry| is known but |device| is nullptr, queue up a request for later. |
| + photo_request_queue_.emplace_back( |
| + session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, |
| + base::Passed(&callback))); |
| } |
| void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| @@ -1025,16 +1049,15 @@ void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { |
| } |
| } |
| -media::VideoCaptureDevice* |
| -VideoCaptureManager::GetVideoCaptureDeviceBySessionId(int session_id) { |
| +VideoCaptureManager::DeviceEntry* |
| +VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| SessionMap::const_iterator session_it = sessions_.find(session_id); |
| if (session_it == sessions_.end()) |
| return nullptr; |
| - DeviceEntry* const device_info = |
| - GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
| - return device_info ? device_info->video_capture_device() : nullptr; |
| + return GetDeviceEntryByTypeAndId(session_it->second.type, |
| + session_it->second.id); |
| } |
| VideoCaptureManager::DeviceEntry* |
| @@ -1125,6 +1148,41 @@ void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( |
| #endif |
| } |
| +void VideoCaptureManager::DoGetPhotoCapabilities( |
| + VideoCaptureDevice::GetPhotoCapabilitiesCallback callback, |
| + VideoCaptureDevice* device) { |
| + // Unretained() is safe to use here because |device| would be null if it |
| + // was scheduled for shutdown and destruction, and because this task is |
| + // guaranteed to run before the task that destroys the |device|. |
| + device_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities, |
| + base::Unretained(device), base::Passed(&callback))); |
| +} |
| + |
| +void VideoCaptureManager::DoSetPhotoOptions( |
| + VideoCaptureDevice::SetPhotoOptionsCallback callback, |
| + media::mojom::PhotoSettingsPtr settings, |
| + VideoCaptureDevice* device) { |
| + // Unretained() is safe to use here because |device| would be null if it |
| + // was scheduled for shutdown and destruction, and because this task is |
| + // guaranteed to run before the task that destroys the |device|. |
| + device_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device), |
| + base::Passed(&settings), base::Passed(&callback))); |
| +} |
| + |
| +void VideoCaptureManager::DoTakePhoto( |
| + VideoCaptureDevice::TakePhotoCallback callback, |
| + VideoCaptureDevice* device) { |
| + // Unretained() is safe to use here because |device| would be null if it |
| + // was scheduled for shutdown and destruction, and because this task is |
| + // guaranteed to run before the task that destroys the |device|. |
| + device_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto, |
| + base::Unretained(device), base::Passed(&callback))); |
| +} |
| + |
| #if defined(OS_MACOSX) |
| void VideoCaptureManager::OnDeviceLayerInitialized( |
| const base::Closure& and_then) { |