 Chromium Code Reviews
 Chromium Code Reviews Issue 2824883005:
  [Mojo Video Capture] Stop service when last client disconnects.  (Closed)
    
  
    Issue 2824883005:
  [Mojo Video Capture] Stop service when last client disconnects.  (Closed) 
  | Index: services/video_capture/device_media_to_mojo_adapter.cc | 
| diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc | 
| index ea7656a2efa153af72827e4d57c8035cc10fcfd5..57221a7ad97fdee5338781a9a2b77e26dd0ff3d7 100644 | 
| --- a/services/video_capture/device_media_to_mojo_adapter.cc | 
| +++ b/services/video_capture/device_media_to_mojo_adapter.cc | 
| @@ -22,27 +22,39 @@ static const int kMaxBufferCount = 3; | 
| namespace video_capture { | 
| DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter( | 
| + std::unique_ptr<service_manager::ServiceContextRef> service_ref, | 
| std::unique_ptr<media::VideoCaptureDevice> device, | 
| const media::VideoCaptureJpegDecoderFactoryCB& | 
| jpeg_decoder_factory_callback) | 
| - : device_(std::move(device)), | 
| + : service_ref_(std::move(service_ref)), | 
| 
mcasas
2017/04/26 22:12:31
nit: I'm not sure we need std::move() here, since
 
chfremer
2017/04/26 23:33:35
Removing the std::move() gives the following error
 | 
| + device_(std::move(device)), | 
| jpeg_decoder_factory_callback_(jpeg_decoder_factory_callback), | 
| - device_running_(false) {} | 
| + device_started_(false) {} | 
| DeviceMediaToMojoAdapter::~DeviceMediaToMojoAdapter() { | 
| 
mcasas
2017/04/26 22:12:31
DCHECK(thread_checker_.CalledOnValidThread());
 
chfremer
2017/04/26 23:33:35
Done.
 | 
| - if (device_running_) | 
| + if (device_started_) | 
| device_->StopAndDeAllocate(); | 
| } | 
| void DeviceMediaToMojoAdapter::Start( | 
| const media::VideoCaptureParams& requested_settings, | 
| mojom::ReceiverPtr receiver) { | 
| + DCHECK(thread_checker_.CalledOnValidThread()); | 
| receiver.set_connection_error_handler( | 
| base::Bind(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose, | 
| base::Unretained(this))); | 
| - auto media_receiver = | 
| + auto receiver_adapter = | 
| base::MakeUnique<ReceiverMojoToMediaAdapter>(std::move(receiver)); | 
| + // We must hold on something that allows us to unsubscribe from | 
| + // receiver.set_connection_error_handler() when we stop the device. Otherwise, | 
| + // we may receive a corresponding callback after having been destroyed. | 
| + // This happens when the deletion of |receiver| is delayed (scheduled to a | 
| + // task runner) when we release |device_|, as is the case when using | 
| + // ReceiverOnTaskRunner. | 
| + receiver_adapter_ptr_ = receiver_adapter.get(); | 
| + auto media_receiver = base::MakeUnique<ReceiverOnTaskRunner>( | 
| + std::move(receiver_adapter), base::ThreadTaskRunnerHandle::Get()); | 
| // Create a dedicated buffer pool for the device usage session. | 
| auto buffer_tracker_factory = | 
| @@ -55,23 +67,29 @@ void DeviceMediaToMojoAdapter::Start( | 
| std::move(media_receiver), buffer_pool, jpeg_decoder_factory_callback_); | 
| device_->AllocateAndStart(requested_settings, std::move(device_client)); | 
| - device_running_ = true; | 
| + device_started_ = true; | 
| } | 
| void DeviceMediaToMojoAdapter::OnReceiverReportingUtilization( | 
| int32_t frame_feedback_id, | 
| double utilization) { | 
| + DCHECK(thread_checker_.CalledOnValidThread()); | 
| device_->OnUtilizationReport(frame_feedback_id, utilization); | 
| } | 
| void DeviceMediaToMojoAdapter::Stop() { | 
| - if (device_running_ == false) | 
| + DCHECK(thread_checker_.CalledOnValidThread()); | 
| + if (device_started_ == false) | 
| return; | 
| - device_running_ = false; | 
| + device_started_ = false; | 
| + // Unsubscribe from connection error callbacks. | 
| + receiver_adapter_ptr_->ResetConnectionErrorHandler(); | 
| + receiver_adapter_ptr_ = nullptr; | 
| device_->StopAndDeAllocate(); | 
| } | 
| void DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose() { | 
| + DCHECK(thread_checker_.CalledOnValidThread()); | 
| Stop(); | 
| } |