| Index: content/browser/renderer_host/media/service_video_capture_device_launcher.cc
|
| diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
|
| index 4c86c448638cc39f1665e20a9a52664c24e6452e..522570ae017b9cb83091ee4e9f63c4ee556b43f1 100644
|
| --- a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
|
| +++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
|
| @@ -57,7 +57,9 @@ void ConcludeLaunchDeviceWithFailure(
|
|
|
| ServiceVideoCaptureDeviceLauncher::ServiceVideoCaptureDeviceLauncher(
|
| video_capture::mojom::DeviceFactoryPtr* device_factory)
|
| - : device_factory_(device_factory), state_(State::READY_TO_LAUNCH) {}
|
| + : device_factory_(device_factory),
|
| + state_(State::READY_TO_LAUNCH),
|
| + callbacks_(nullptr) {}
|
|
|
| ServiceVideoCaptureDeviceLauncher::~ServiceVideoCaptureDeviceLauncher() {
|
| DCHECK(sequence_checker_.CalledOnValidSequence());
|
| @@ -88,18 +90,27 @@ void ServiceVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
| return;
|
| }
|
| video_capture::mojom::DevicePtr device;
|
| - // We need the temporary variable |device_request| in order to guarantee that
|
| - // mojo::MakeRequest(&device) happens before base::Passed(&device).
|
| auto device_request = mojo::MakeRequest(&device);
|
| + // Ownership of |done_cb| is moved to |this|. It is not sufficient to attach
|
| + // it to the callback passed to |(*device_factory_)->CreateDevice()|, because
|
| + // |device_factory_| may get torn down before the callback is invoked.
|
| + done_cb_ = std::move(done_cb);
|
| + callbacks_ = callbacks;
|
| + // Use of Unretained(this) is safe, because |done_cb_| guarantees that |this|
|
| + // stays alive.
|
| + device.set_connection_error_handler(
|
| + base::Bind(&ServiceVideoCaptureDeviceLauncher::
|
| + OnConnectionLostWhileWaitingForCallback,
|
| + base::Unretained(this)));
|
| (*device_factory_)
|
| ->CreateDevice(
|
| device_id, std::move(device_request),
|
| base::Bind(
|
| - // Use of Unretained |this| is safe, because |done_cb| guarantees
|
| + // Use of Unretained |this| is safe, because |done_cb_| guarantees
|
| // that |this| stays alive.
|
| &ServiceVideoCaptureDeviceLauncher::OnCreateDeviceCallback,
|
| base::Unretained(this), params, base::Passed(&device),
|
| - std::move(receiver), callbacks, base::Passed(&done_cb)));
|
| + std::move(receiver)));
|
| state_ = State::DEVICE_START_IN_PROGRESS;
|
| }
|
|
|
| @@ -113,24 +124,39 @@ void ServiceVideoCaptureDeviceLauncher::OnCreateDeviceCallback(
|
| const media::VideoCaptureParams& params,
|
| video_capture::mojom::DevicePtr device,
|
| base::WeakPtr<media::VideoFrameReceiver> receiver,
|
| - Callbacks* callbacks,
|
| - base::OnceClosure done_cb,
|
| video_capture::mojom::DeviceAccessResultCode result_code) {
|
| DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(callbacks_);
|
| + DCHECK(done_cb_);
|
| + device.set_connection_error_handler(base::Bind(&base::DoNothing));
|
| const bool abort_requested = (state_ == State::DEVICE_START_ABORTING);
|
| state_ = State::READY_TO_LAUNCH;
|
| + Callbacks* callbacks = callbacks_;
|
| + callbacks_ = nullptr;
|
| switch (result_code) {
|
| case video_capture::mojom::DeviceAccessResultCode::SUCCESS:
|
| ConcludeLaunchDeviceWithSuccess(abort_requested, params,
|
| std::move(device), std::move(receiver),
|
| - callbacks, std::move(done_cb));
|
| + callbacks, std::move(done_cb_));
|
| return;
|
| case video_capture::mojom::DeviceAccessResultCode::ERROR_DEVICE_NOT_FOUND:
|
| case video_capture::mojom::DeviceAccessResultCode::NOT_INITIALIZED:
|
| ConcludeLaunchDeviceWithFailure(abort_requested, callbacks,
|
| - std::move(done_cb));
|
| + std::move(done_cb_));
|
| return;
|
| }
|
| }
|
|
|
| +void ServiceVideoCaptureDeviceLauncher::
|
| + OnConnectionLostWhileWaitingForCallback() {
|
| + DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(callbacks_);
|
| + const bool abort_requested = (state_ == State::DEVICE_START_ABORTING);
|
| + state_ = State::READY_TO_LAUNCH;
|
| + Callbacks* callbacks = callbacks_;
|
| + callbacks_ = nullptr;
|
| + ConcludeLaunchDeviceWithFailure(abort_requested, callbacks,
|
| + std::move(done_cb_));
|
| +}
|
| +
|
| } // namespace content
|
|
|