Commit 86e7aa88 authored by Christian Fremerey's avatar Christian Fremerey Committed by Commit Bot

[Video Capture] Switch usage in Chromium Browser process to the new multi-client API

The video capture service offers a new API for opening capture devices
in a way that allows them to be shared by multiple clients. This CL
switches one such client, i.e. the Chromium Browser process, over to
that new API. This enables other clients to share access to capture
devices with the Chromium Browser process.

Design Doc: https://docs.google.com/document/d/1mYnsZfLBRmbsDpUtfb6C7dzhfw2Kcxg_-uiG_6MnWVQ/edit?usp=sharing

Test: content_browsertests --gtest_filter=WebRtcVideoCaptureSharedDeviceBrowserTest.*
Bug: 783442
Change-Id: I9c236f03e315cdafdc07429f3213fa4d11b43b34
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1399454
Commit-Queue: Christian Fremerey <chfremer@chromium.org>
Reviewed-by: default avatarMustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatarEmircan Uysaler <emircan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#637405}
parent dd3e44cc
......@@ -1491,8 +1491,8 @@ jumbo_source_set("browser") {
"renderer_host/media/old_render_frame_audio_output_stream_factory.h",
"renderer_host/media/peer_connection_tracker_host.cc",
"renderer_host/media/peer_connection_tracker_host.h",
"renderer_host/media/ref_counted_video_capture_factory.cc",
"renderer_host/media/ref_counted_video_capture_factory.h",
"renderer_host/media/ref_counted_video_source_provider.cc",
"renderer_host/media/ref_counted_video_source_provider.h",
"renderer_host/media/render_frame_audio_input_stream_factory.cc",
"renderer_host/media/render_frame_audio_input_stream_factory.h",
"renderer_host/media/render_frame_audio_output_stream_factory.cc",
......
......@@ -2,34 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/renderer_host/media/ref_counted_video_capture_factory.h"
#include "content/browser/renderer_host/media/ref_counted_video_source_provider.h"
namespace content {
RefCountedVideoCaptureFactory::RefCountedVideoCaptureFactory(
video_capture::mojom::DeviceFactoryPtr device_factory,
RefCountedVideoSourceProvider::RefCountedVideoSourceProvider(
video_capture::mojom::VideoSourceProviderPtr source_provider,
video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
base::OnceClosure destruction_cb)
: device_factory_(std::move(device_factory)),
: source_provider_(std::move(source_provider)),
device_factory_provider_(std::move(device_factory_provider)),
destruction_cb_(std::move(destruction_cb)),
weak_ptr_factory_(this) {}
RefCountedVideoCaptureFactory::~RefCountedVideoCaptureFactory() {
RefCountedVideoSourceProvider::~RefCountedVideoSourceProvider() {
std::move(destruction_cb_).Run();
}
base::WeakPtr<RefCountedVideoCaptureFactory>
RefCountedVideoCaptureFactory::GetWeakPtr() {
base::WeakPtr<RefCountedVideoSourceProvider>
RefCountedVideoSourceProvider::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void RefCountedVideoCaptureFactory::ShutdownServiceAsap() {
void RefCountedVideoSourceProvider::ShutdownServiceAsap() {
device_factory_provider_->ShutdownServiceAsap();
}
void RefCountedVideoCaptureFactory::ReleaseFactoryForTesting() {
device_factory_.reset();
void RefCountedVideoSourceProvider::ReleaseProviderForTesting() {
source_provider_.reset();
}
} // namespace content
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_H_
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_SOURCE_PROVIDER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_SOURCE_PROVIDER_H_
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
#include "services/video_capture/public/mojom/video_source_provider.mojom.h"
namespace content {
......@@ -17,36 +17,35 @@ namespace content {
// Since instances of this class do not guarantee that the connection stays open
// for its entire lifetime, clients must verify that the connection is bound
// before using it.
class CONTENT_EXPORT RefCountedVideoCaptureFactory
: public base::RefCounted<RefCountedVideoCaptureFactory> {
class CONTENT_EXPORT RefCountedVideoSourceProvider
: public base::RefCounted<RefCountedVideoSourceProvider> {
public:
RefCountedVideoCaptureFactory(
video_capture::mojom::DeviceFactoryPtr device_factory,
RefCountedVideoSourceProvider(
video_capture::mojom::VideoSourceProviderPtr source_provider,
video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
base::OnceClosure destruction_cb);
base::WeakPtr<RefCountedVideoCaptureFactory> GetWeakPtr();
base::WeakPtr<RefCountedVideoSourceProvider> GetWeakPtr();
const video_capture::mojom::DeviceFactoryPtr& device_factory() {
return device_factory_;
const video_capture::mojom::VideoSourceProviderPtr& source_provider() {
return source_provider_;
}
void ShutdownServiceAsap();
void ReleaseFactoryForTesting();
void ReleaseProviderForTesting();
private:
friend class base::RefCounted<RefCountedVideoCaptureFactory>;
~RefCountedVideoCaptureFactory();
friend class base::RefCounted<RefCountedVideoSourceProvider>;
~RefCountedVideoSourceProvider();
video_capture::mojom::DeviceFactoryPtr device_factory_;
video_capture::mojom::VideoSourceProviderPtr source_provider_;
video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider_;
base::OnceClosure destruction_cb_;
base::WeakPtrFactory<RefCountedVideoCaptureFactory> weak_ptr_factory_;
base::WeakPtrFactory<RefCountedVideoSourceProvider> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(RefCountedVideoCaptureFactory);
DISALLOW_COPY_AND_ASSIGN(RefCountedVideoSourceProvider);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_H_
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_SOURCE_PROVIDER_H_
......@@ -3,19 +3,29 @@
// found in the LICENSE file.
#include "content/browser/renderer_host/media/service_launched_video_capture_device.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
namespace content {
ServiceLaunchedVideoCaptureDevice::ServiceLaunchedVideoCaptureDevice(
video_capture::mojom::DevicePtr device,
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb)
: device_(std::move(device)),
: source_(std::move(source)),
subscription_(std::move(subscription)),
connection_lost_cb_(std::move(connection_lost_cb)) {
// Unretained |this| is safe, because |this| owns |device_|.
device_.set_connection_error_handler(base::BindOnce(
&ServiceLaunchedVideoCaptureDevice::OnLostConnectionToDevice,
base::Unretained(this)));
// Unretained |this| is safe, because |this| owns |source_|.
source_.set_connection_error_handler(
base::BindOnce(&ServiceLaunchedVideoCaptureDevice::
OnLostConnectionToSourceOrSubscription,
base::Unretained(this)));
// Unretained |this| is safe, because |this| owns |subscription_|.
subscription_.set_connection_error_handler(
base::BindOnce(&ServiceLaunchedVideoCaptureDevice::
OnLostConnectionToSourceOrSubscription,
base::Unretained(this)));
}
ServiceLaunchedVideoCaptureDevice::~ServiceLaunchedVideoCaptureDevice() {
......@@ -25,7 +35,7 @@ ServiceLaunchedVideoCaptureDevice::~ServiceLaunchedVideoCaptureDevice() {
void ServiceLaunchedVideoCaptureDevice::GetPhotoState(
media::VideoCaptureDevice::GetPhotoStateCallback callback) const {
DCHECK(sequence_checker_.CalledOnValidSequence());
device_->GetPhotoState(base::BindOnce(
subscription_->GetPhotoState(base::BindOnce(
&ServiceLaunchedVideoCaptureDevice::OnGetPhotoStateResponse,
base::Unretained(this), std::move(callback)));
}
......@@ -34,7 +44,7 @@ void ServiceLaunchedVideoCaptureDevice::SetPhotoOptions(
media::mojom::PhotoSettingsPtr settings,
media::VideoCaptureDevice::SetPhotoOptionsCallback callback) {
DCHECK(sequence_checker_.CalledOnValidSequence());
device_->SetPhotoOptions(
subscription_->SetPhotoOptions(
std::move(settings),
base::BindOnce(
&ServiceLaunchedVideoCaptureDevice::OnSetPhotoOptionsResponse,
......@@ -47,23 +57,25 @@ void ServiceLaunchedVideoCaptureDevice::TakePhoto(
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
"ServiceLaunchedVideoCaptureDevice::TakePhoto",
TRACE_EVENT_SCOPE_PROCESS);
device_->TakePhoto(
subscription_->TakePhoto(
base::BindOnce(&ServiceLaunchedVideoCaptureDevice::OnTakePhotoResponse,
base::Unretained(this), std::move(callback)));
}
void ServiceLaunchedVideoCaptureDevice::MaybeSuspendDevice() {
DCHECK(sequence_checker_.CalledOnValidSequence());
device_->MaybeSuspend();
subscription_->Suspend(base::DoNothing());
}
void ServiceLaunchedVideoCaptureDevice::ResumeDevice() {
DCHECK(sequence_checker_.CalledOnValidSequence());
device_->Resume();
subscription_->Resume();
}
void ServiceLaunchedVideoCaptureDevice::RequestRefreshFrame() {
// Ignore this call.
DCHECK(sequence_checker_.CalledOnValidSequence());
// Nothing to do here. The video capture service does not support refresh
// frames.
}
void ServiceLaunchedVideoCaptureDevice::SetDesktopCaptureWindowIdAsync(
......@@ -78,11 +90,16 @@ void ServiceLaunchedVideoCaptureDevice::SetDesktopCaptureWindowIdAsync(
void ServiceLaunchedVideoCaptureDevice::OnUtilizationReport(
int frame_feedback_id,
double utilization) {
// Ignore this call.
DCHECK(sequence_checker_.CalledOnValidSequence());
// Nothing to do here. The video capture service does not support utilization
// reporting.
}
void ServiceLaunchedVideoCaptureDevice::OnLostConnectionToDevice() {
void ServiceLaunchedVideoCaptureDevice::
OnLostConnectionToSourceOrSubscription() {
DCHECK(sequence_checker_.CalledOnValidSequence());
source_.reset();
subscription_.reset();
base::ResetAndReturn(&connection_lost_cb_).Run();
}
......
......@@ -7,7 +7,7 @@
#include "content/browser/renderer_host/media/video_capture_provider.h"
#include "content/public/browser/video_capture_device_launcher.h"
#include "services/video_capture/public/mojom/device.mojom.h"
#include "services/video_capture/public/mojom/video_source.mojom.h"
namespace content {
......@@ -15,8 +15,10 @@ namespace content {
// service.
class ServiceLaunchedVideoCaptureDevice : public LaunchedVideoCaptureDevice {
public:
ServiceLaunchedVideoCaptureDevice(video_capture::mojom::DevicePtr device,
base::OnceClosure connection_lost_cb);
ServiceLaunchedVideoCaptureDevice(
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb);
~ServiceLaunchedVideoCaptureDevice() override;
// LaunchedVideoCaptureDevice implementation.
......@@ -37,7 +39,7 @@ class ServiceLaunchedVideoCaptureDevice : public LaunchedVideoCaptureDevice {
void OnUtilizationReport(int frame_feedback_id, double utilization) override;
private:
void OnLostConnectionToDevice();
void OnLostConnectionToSourceOrSubscription();
void OnGetPhotoStateResponse(
media::VideoCaptureDevice::GetPhotoStateCallback callback,
media::mojom::PhotoStatePtr capabilities) const;
......@@ -48,7 +50,8 @@ class ServiceLaunchedVideoCaptureDevice : public LaunchedVideoCaptureDevice {
media::VideoCaptureDevice::TakePhotoCallback callback,
media::mojom::BlobPtr blob);
video_capture::mojom::DevicePtr device_;
video_capture::mojom::VideoSourcePtr source_;
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription_;
base::OnceClosure connection_lost_cb_;
base::SequenceChecker sequence_checker_;
};
......
......@@ -20,37 +20,26 @@ namespace content {
namespace {
void ConcludeLaunchDeviceWithSuccess(
const media::VideoCaptureParams& params,
video_capture::mojom::DevicePtr device,
base::WeakPtr<media::VideoFrameReceiver> receiver,
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb,
VideoCaptureDeviceLauncher::Callbacks* callbacks,
base::OnceClosure done_cb) {
auto receiver_adapter =
std::make_unique<video_capture::ReceiverMediaToMojoAdapter>(
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
std::move(receiver), base::CreateSingleThreadTaskRunnerWithTraits(
{BrowserThread::IO})));
video_capture::mojom::ReceiverPtr receiver_proxy;
mojo::MakeStrongBinding<video_capture::mojom::Receiver>(
std::move(receiver_adapter), mojo::MakeRequest(&receiver_proxy));
media::VideoCaptureParams new_params = params;
new_params.power_line_frequency =
media::VideoCaptureDevice::GetPowerLineFrequency(params);
device->Start(new_params, std::move(receiver_proxy));
subscription->Activate();
callbacks->OnDeviceLaunched(
std::make_unique<ServiceLaunchedVideoCaptureDevice>(
std::move(device), std::move(connection_lost_cb)));
std::move(source), std::move(subscription),
std::move(connection_lost_cb)));
base::ResetAndReturn(&done_cb).Run();
}
void ConcludeLaunchDeviceWithFailure(
bool abort_requested,
media::VideoCaptureError error,
scoped_refptr<RefCountedVideoCaptureFactory> device_factory,
scoped_refptr<RefCountedVideoSourceProvider> service_connection,
VideoCaptureDeviceLauncher::Callbacks* callbacks,
base::OnceClosure done_cb) {
device_factory.reset();
service_connection.reset();
if (abort_requested)
callbacks->OnDeviceLaunchAborted();
else
......@@ -61,8 +50,8 @@ void ConcludeLaunchDeviceWithFailure(
} // anonymous namespace
ServiceVideoCaptureDeviceLauncher::ServiceVideoCaptureDeviceLauncher(
ConnectToDeviceFactoryCB connect_to_device_factory_cb)
: connect_to_device_factory_cb_(std::move(connect_to_device_factory_cb)),
ConnectToDeviceFactoryCB connect_to_source_provider_cb)
: connect_to_source_provider_cb_(std::move(connect_to_source_provider_cb)),
state_(State::READY_TO_LAUNCH),
callbacks_(nullptr) {}
......@@ -88,16 +77,14 @@ void ServiceVideoCaptureDeviceLauncher::LaunchDeviceAsync(
return;
}
connect_to_device_factory_cb_.Run(&device_factory_);
if (!device_factory_->device_factory().is_bound()) {
// This can happen when the ServiceVideoCaptureProvider owning
// |device_factory_| loses connection to the service process and resets
// |device_factory_|.
connect_to_source_provider_cb_.Run(&service_connection_);
if (!service_connection_->source_provider().is_bound()) {
// This can happen when the connection to the service was lost.
ConcludeLaunchDeviceWithFailure(
false,
media::VideoCaptureError::
kServiceDeviceLauncherLostConnectionToDeviceFactoryDuringDeviceStart,
std::move(device_factory_), callbacks, std::move(done_cb));
std::move(service_connection_), callbacks, std::move(done_cb));
return;
}
......@@ -105,32 +92,62 @@ void ServiceVideoCaptureDeviceLauncher::LaunchDeviceAsync(
std::ostringstream string_stream;
string_stream
<< "ServiceVideoCaptureDeviceLauncher::LaunchDeviceAsync: Asking "
"video capture service to create device for device_id = "
"video capture service to create source for device_id = "
<< device_id;
receiver->OnLog(string_stream.str());
}
video_capture::mojom::DevicePtr 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.
// it to the callback passed to CreatePushSubscription(), because the
// connection to the service may get torn down before |callbacks| are
// invoked.
done_cb_ = std::move(done_cb);
callbacks_ = callbacks;
video_capture::mojom::VideoSourcePtr source;
service_connection_->source_provider()->GetVideoSource(
device_id, mojo::MakeRequest(&source));
auto receiver_adapter =
std::make_unique<video_capture::ReceiverMediaToMojoAdapter>(
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
std::move(receiver), base::CreateSingleThreadTaskRunnerWithTraits(
{BrowserThread::IO})));
video_capture::mojom::ReceiverPtr receiver_proxy;
mojo::MakeStrongBinding<video_capture::mojom::Receiver>(
std::move(receiver_adapter), mojo::MakeRequest(&receiver_proxy));
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription;
// Create message pipe so that we can subsequently call
// subscription.set_connection_error_handler().
auto subscription_request = mojo::MakeRequest(&subscription);
// Use of Unretained(this) is safe, because |done_cb_| guarantees that |this|
// stays alive.
device.set_connection_error_handler(
subscription.set_connection_error_handler(
base::BindOnce(&ServiceVideoCaptureDeviceLauncher::
OnConnectionLostWhileWaitingForCallback,
base::Unretained(this)));
device_factory_->device_factory()->CreateDevice(
device_id, std::move(device_request),
// TODO(crbug.com/925083)
media::VideoCaptureParams new_params = params;
new_params.power_line_frequency =
media::VideoCaptureDevice::GetPowerLineFrequency(params);
// Note that we set |force_reopen_with_new_settings| to true in order
// to avoid the situation that a requests to open (or reopen) a device
// that has just been closed with different settings ends up getting the old
// settings, because from the perspective of the service, the device was still
// in use. In order to be able to set |force_reopen_with_new_settings|, we
// have to refactor code here and upstream to wait for a callback from the
// service indicating that the device closing is complete.
source->CreatePushSubscription(
std::move(receiver_proxy), new_params,
true /*force_reopen_with_new_settings*/, std::move(subscription_request),
base::BindOnce(
// Use of Unretained |this| is safe, because |done_cb_| guarantees
// that |this| stays alive.
&ServiceVideoCaptureDeviceLauncher::OnCreateDeviceCallback,
base::Unretained(this), params, std::move(device),
std::move(receiver), std::move(connection_lost_cb)));
&ServiceVideoCaptureDeviceLauncher::OnCreatePushSubscriptionCallback,
base::Unretained(this), std::move(source), std::move(subscription),
std::move(connection_lost_cb)));
state_ = State::DEVICE_START_IN_PROGRESS;
}
......@@ -140,40 +157,43 @@ void ServiceVideoCaptureDeviceLauncher::AbortLaunch() {
state_ = State::DEVICE_START_ABORTING;
}
void ServiceVideoCaptureDeviceLauncher::OnCreateDeviceCallback(
const media::VideoCaptureParams& params,
video_capture::mojom::DevicePtr device,
base::WeakPtr<media::VideoFrameReceiver> receiver,
void ServiceVideoCaptureDeviceLauncher::OnCreatePushSubscriptionCallback(
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb,
video_capture::mojom::DeviceAccessResultCode result_code) {
video_capture::mojom::CreatePushSubscriptionResultCode result_code,
const media::VideoCaptureParams& params) {
DCHECK(sequence_checker_.CalledOnValidSequence());
DCHECK(callbacks_);
DCHECK(done_cb_);
device.set_connection_error_handler(base::DoNothing());
subscription.set_connection_error_handler(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:
case video_capture::mojom::CreatePushSubscriptionResultCode::
kCreatedWithRequestedSettings: // Fall through.
case video_capture::mojom::CreatePushSubscriptionResultCode::
kCreatedWithDifferentSettings:
if (abort_requested) {
device.reset();
device_factory_.reset();
subscription.reset();
source.reset();
service_connection_.reset();
callbacks->OnDeviceLaunchAborted();
base::ResetAndReturn(&done_cb_).Run();
return;
}
ConcludeLaunchDeviceWithSuccess(
params, std::move(device), std::move(receiver),
std::move(source), std::move(subscription),
std::move(connection_lost_cb), callbacks, std::move(done_cb_));
return;
case video_capture::mojom::DeviceAccessResultCode::ERROR_DEVICE_NOT_FOUND:
case video_capture::mojom::DeviceAccessResultCode::NOT_INITIALIZED:
case video_capture::mojom::CreatePushSubscriptionResultCode::kFailed:
ConcludeLaunchDeviceWithFailure(
abort_requested,
media::VideoCaptureError::
kServiceDeviceLauncherServiceRespondedWithDeviceNotFound,
std::move(device_factory_), callbacks, std::move(done_cb_));
std::move(service_connection_), callbacks, std::move(done_cb_));
return;
}
}
......@@ -190,7 +210,7 @@ void ServiceVideoCaptureDeviceLauncher::
abort_requested,
media::VideoCaptureError::
kServiceDeviceLauncherConnectionLostWhileWaitingForCallback,
std::move(device_factory_), callbacks, std::move(done_cb_));
std::move(service_connection_), callbacks, std::move(done_cb_));
}
} // namespace content
......@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_SERVICE_VIDEO_CAPTURE_DEVICE_LAUNCHER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_SERVICE_VIDEO_CAPTURE_DEVICE_LAUNCHER_H_
#include "content/browser/renderer_host/media/ref_counted_video_capture_factory.h"
#include "content/browser/renderer_host/media/ref_counted_video_source_provider.h"
#include "content/browser/renderer_host/media/video_capture_provider.h"
#include "content/public/browser/video_capture_device_launcher.h"
#include "services/video_capture/public/mojom/device_factory.mojom.h"
......@@ -18,12 +18,12 @@ namespace content {
class CONTENT_EXPORT ServiceVideoCaptureDeviceLauncher
: public VideoCaptureDeviceLauncher {
public:
// Receives an instance via output parameter |factory|.
// Receives an instance via output parameter |out_provider|.
using ConnectToDeviceFactoryCB = base::RepeatingCallback<void(
scoped_refptr<RefCountedVideoCaptureFactory>*)>;
scoped_refptr<RefCountedVideoSourceProvider>* out_provider)>;
explicit ServiceVideoCaptureDeviceLauncher(
ConnectToDeviceFactoryCB connect_to_device_factory_cb);
ConnectToDeviceFactoryCB connect_to_source_provider_cb);
~ServiceVideoCaptureDeviceLauncher() override;
// VideoCaptureDeviceLauncher implementation.
......@@ -45,17 +45,17 @@ class CONTENT_EXPORT ServiceVideoCaptureDeviceLauncher
DEVICE_START_ABORTING
};
void OnCreateDeviceCallback(
const media::VideoCaptureParams& params,
video_capture::mojom::DevicePtr device,
base::WeakPtr<media::VideoFrameReceiver> receiver,
void OnCreatePushSubscriptionCallback(
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb,
video_capture::mojom::DeviceAccessResultCode result_code);
video_capture::mojom::CreatePushSubscriptionResultCode result_code,
const media::VideoCaptureParams& params);
void OnConnectionLostWhileWaitingForCallback();
ConnectToDeviceFactoryCB connect_to_device_factory_cb_;
scoped_refptr<RefCountedVideoCaptureFactory> device_factory_;
ConnectToDeviceFactoryCB connect_to_source_provider_cb_;
scoped_refptr<RefCountedVideoSourceProvider> service_connection_;
State state_;
base::SequenceChecker sequence_checker_;
base::OnceClosure done_cb_;
......
......@@ -59,7 +59,7 @@ ServiceVideoCaptureProvider::ServiceVideoCaptureProvider(
: connector_(connector ? connector->Clone() : nullptr),
create_accelerator_factory_cb_(std::move(create_accelerator_factory_cb)),
emit_log_message_cb_(std::move(emit_log_message_cb)),
launcher_has_connected_to_device_factory_(false),
launcher_has_connected_to_source_provider_(false),
service_listener_binding_(this),
weak_ptr_factory_(this) {
base::PostTaskWithTraits(
......@@ -86,7 +86,7 @@ ServiceVideoCaptureProvider::CreateDeviceLauncher() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
return std::make_unique<ServiceVideoCaptureDeviceLauncher>(
base::BindRepeating(
&ServiceVideoCaptureProvider::OnLauncherConnectingToDeviceFactory,
&ServiceVideoCaptureProvider::OnLauncherConnectingToSourceProvider,
weak_ptr_factory_.GetWeakPtr()));
}
......@@ -106,7 +106,7 @@ void ServiceVideoCaptureProvider::OnServiceStarted(
mojo::MakeStrongBinding(
std::make_unique<VirtualVideoCaptureDevicesChangedObserver>(),
mojo::MakeRequest(&observer));
service_connection->device_factory()->RegisterVirtualDevicesChangedObserver(
service_connection->source_provider()->RegisterVirtualDevicesChangedObserver(
std::move(observer),
true /*raise_event_if_virtual_devices_already_present*/);
}
......@@ -144,14 +144,14 @@ void ServiceVideoCaptureProvider::RegisterServiceListenerOnIOThread() {
service_manager->AddListener(std::move(listener));
}
void ServiceVideoCaptureProvider::OnLauncherConnectingToDeviceFactory(
scoped_refptr<RefCountedVideoCaptureFactory>* out_factory) {
void ServiceVideoCaptureProvider::OnLauncherConnectingToSourceProvider(
scoped_refptr<RefCountedVideoSourceProvider>* out_provider) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
launcher_has_connected_to_device_factory_ = true;
*out_factory = LazyConnectToService();
launcher_has_connected_to_source_provider_ = true;
*out_provider = LazyConnectToService();
}
scoped_refptr<RefCountedVideoCaptureFactory>
scoped_refptr<RefCountedVideoSourceProvider>
ServiceVideoCaptureProvider::LazyConnectToService() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
......@@ -163,7 +163,7 @@ ServiceVideoCaptureProvider::LazyConnectToService() {
video_capture::uma::LogVideoCaptureServiceEvent(
video_capture::uma::BROWSER_CONNECTING_TO_SERVICE);
if (time_of_last_uninitialize_ != base::TimeTicks()) {
if (launcher_has_connected_to_device_factory_) {
if (launcher_has_connected_to_source_provider_) {
video_capture::uma::LogDurationUntilReconnectAfterCapture(
base::TimeTicks::Now() - time_of_last_uninitialize_);
} else {
......@@ -172,7 +172,7 @@ ServiceVideoCaptureProvider::LazyConnectToService() {
}
}
launcher_has_connected_to_device_factory_ = false;
launcher_has_connected_to_source_provider_ = false;
time_of_last_connect_ = base::TimeTicks::Now();
video_capture::mojom::AcceleratorFactoryPtr accelerator_factory;
......@@ -189,14 +189,14 @@ ServiceVideoCaptureProvider::LazyConnectToService() {
device_factory_provider->InjectGpuDependencies(
std::move(accelerator_factory));
video_capture::mojom::DeviceFactoryPtr device_factory;
device_factory_provider->ConnectToDeviceFactory(
mojo::MakeRequest(&device_factory));
device_factory.set_connection_error_handler(base::BindOnce(
&ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory,
video_capture::mojom::VideoSourceProviderPtr source_provider;
device_factory_provider->ConnectToVideoSourceProvider(
mojo::MakeRequest(&source_provider));
source_provider.set_connection_error_handler(base::BindOnce(
&ServiceVideoCaptureProvider::OnLostConnectionToSourceProvider,
weak_ptr_factory_.GetWeakPtr()));
auto result = base::MakeRefCounted<RefCountedVideoCaptureFactory>(
std::move(device_factory), std::move(device_factory_provider),
auto result = base::MakeRefCounted<RefCountedVideoSourceProvider>(
std::move(source_provider), std::move(device_factory_provider),
base::BindOnce(&ServiceVideoCaptureProvider::OnServiceConnectionClosed,
weak_ptr_factory_.GetWeakPtr(),
ReasonForDisconnect::kUnused));
......@@ -211,7 +211,7 @@ void ServiceVideoCaptureProvider::GetDeviceInfosAsyncForRetry(
auto service_connection = LazyConnectToService();
// Use a ScopedCallbackRunner to make sure that |result_callback| gets
// invoked with an empty result in case that the service drops the request.
service_connection->device_factory()->GetDeviceInfos(
service_connection->source_provider()->GetSourceInfos(
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(&ServiceVideoCaptureProvider::OnDeviceInfosReceived,
weak_ptr_factory_.GetWeakPtr(), service_connection,
......@@ -220,7 +220,7 @@ void ServiceVideoCaptureProvider::GetDeviceInfosAsyncForRetry(
}
void ServiceVideoCaptureProvider::OnDeviceInfosReceived(
scoped_refptr<RefCountedVideoCaptureFactory> service_connection,
scoped_refptr<RefCountedVideoSourceProvider> service_connection,
GetDeviceInfosCallback result_callback,
int retry_count,
const std::vector<media::VideoCaptureDeviceInfo>& infos) {
......@@ -254,10 +254,10 @@ void ServiceVideoCaptureProvider::OnDeviceInfosReceived(
base::ResetAndReturn(&result_callback).Run(infos);
}
void ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory() {
void ServiceVideoCaptureProvider::OnLostConnectionToSourceProvider() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
emit_log_message_cb_.Run(
"ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory");
"ServiceVideoCaptureProvider::OnLostConnectionToSourceProvider");
// This may indicate that the video capture service has crashed. Uninitialize
// here, so that a new connection will be established when clients try to
// reconnect.
......@@ -272,7 +272,7 @@ void ServiceVideoCaptureProvider::OnServiceConnectionClosed(
switch (reason) {
case ReasonForDisconnect::kShutdown:
case ReasonForDisconnect::kUnused:
if (launcher_has_connected_to_device_factory_) {
if (launcher_has_connected_to_source_provider_) {
video_capture::uma::LogVideoCaptureServiceEvent(
video_capture::uma::
BROWSER_CLOSING_CONNECTION_TO_SERVICE_AFTER_CAPTURE);
......
......@@ -7,7 +7,7 @@
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/ref_counted_video_capture_factory.h"
#include "content/browser/renderer_host/media/ref_counted_video_source_provider.h"
#include "content/browser/renderer_host/media/video_capture_provider.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/connector.h"
......@@ -66,31 +66,31 @@ class CONTENT_EXPORT ServiceVideoCaptureProvider
void RegisterServiceListenerOnIOThread();
// Note, this needs to have void return value because of "weak_ptrs can only
// bind to methods without return values".
void OnLauncherConnectingToDeviceFactory(
scoped_refptr<RefCountedVideoCaptureFactory>* out_factory);
// Discarding the returned RefCountedVideoCaptureFactory indicates that the
void OnLauncherConnectingToSourceProvider(
scoped_refptr<RefCountedVideoSourceProvider>* out_provider);
// Discarding the returned RefCountedVideoSourceProvider indicates that the
// caller no longer requires the connection to the service and allows it to
// disconnect.
scoped_refptr<RefCountedVideoCaptureFactory> LazyConnectToService()
scoped_refptr<RefCountedVideoSourceProvider> LazyConnectToService()
WARN_UNUSED_RESULT;
void GetDeviceInfosAsyncForRetry(GetDeviceInfosCallback result_callback,
int retry_count);
void OnDeviceInfosReceived(
scoped_refptr<RefCountedVideoCaptureFactory> service_connection,
scoped_refptr<RefCountedVideoSourceProvider> service_connection,
GetDeviceInfosCallback result_callback,
int retry_count,
const std::vector<media::VideoCaptureDeviceInfo>& infos);
void OnLostConnectionToDeviceFactory();
void OnLostConnectionToSourceProvider();
void OnServiceConnectionClosed(ReasonForDisconnect reason);
std::unique_ptr<service_manager::Connector> connector_;
CreateAcceleratorFactoryCallback create_accelerator_factory_cb_;
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb_;
base::WeakPtr<RefCountedVideoCaptureFactory> weak_service_connection_;
base::WeakPtr<RefCountedVideoSourceProvider> weak_service_connection_;
bool launcher_has_connected_to_device_factory_;
bool launcher_has_connected_to_source_provider_;
base::TimeTicks time_of_last_connect_;
base::TimeTicks time_of_last_uninitialize_;
......
......@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIRTUAL_VIDEO_CAPTURE_DEVICES_CHANGED_OBSERVER_H_
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
namespace content {
......
......@@ -20,6 +20,7 @@
#include "services/video_capture/public/mojom/constants.mojom.h"
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#include "services/video_capture/public/mojom/virtual_device.mojom.h"
namespace content {
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "media/base/media_switches.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/video_capture/public/cpp/mock_receiver.h"
#include "services/video_capture/public/mojom/constants.mojom.h"
#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
#include "services/video_capture/public/mojom/video_source.mojom.h"
#include "services/video_capture/public/mojom/video_source_provider.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
using testing::_;
using testing::AtLeast;
using testing::InvokeWithoutArgs;
using testing::Return;
namespace content {
namespace {
static const char kVideoCaptureHtmlFile[] = "/media/video_capture_test.html";
static const char kStartVideoCaptureAndVerify[] =
"startVideoCaptureAndVerifySize(%d, %d)";
static const gfx::Size kVideoSize(320, 200);
} // namespace
// Integration test sets up a single fake device and obtains a connection to the
// video capture service via the Browser process' service manager. It then
// opens the device from clients. One client is the test calling into the
// video capture service directly. The second client is the Browser, which the
// test exercises through JavaScript.
class WebRtcVideoCaptureSharedDeviceBrowserTest : public ContentBrowserTest {
public:
WebRtcVideoCaptureSharedDeviceBrowserTest() : weak_factory_(this) {
scoped_feature_list_.InitAndEnableFeature(features::kMojoVideoCapture);
}
~WebRtcVideoCaptureSharedDeviceBrowserTest() override {}
void OpenDeviceViaService(base::OnceClosure done_cb) {
connector_->BindInterface(video_capture::mojom::kServiceName,
&device_factory_provider_);
device_factory_provider_->ConnectToVideoSourceProvider(
mojo::MakeRequest(&video_source_provider_));
video_source_provider_->GetSourceInfos(base::BindOnce(
&WebRtcVideoCaptureSharedDeviceBrowserTest::OnSourceInfosReceived,
weak_factory_.GetWeakPtr(), std::move(done_cb)));
}
void OpenDeviceInRendererAndWaitForPlaying() {
DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
embedded_test_server()->StartAcceptingConnections();
GURL url(embedded_test_server()->GetURL(kVideoCaptureHtmlFile));
NavigateToURL(shell(), url);
const std::string javascript_to_execute = base::StringPrintf(
kStartVideoCaptureAndVerify, kVideoSize.width(), kVideoSize.height());
std::string result;
// Start video capture and wait until it started rendering
ASSERT_TRUE(
ExecuteScriptAndExtractString(shell(), javascript_to_execute, &result));
ASSERT_EQ("OK", result);
}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
}
void SetUp() override {
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
EnablePixelOutput();
ContentBrowserTest::SetUp();
}
void Initialize() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
auto* connection = content::ServiceManagerConnection::GetForProcess();
ASSERT_TRUE(connection);
auto* connector = connection->GetConnector();
ASSERT_TRUE(connector);
// We need to clone it so that we can use the clone on a different thread.
connector_ = connector->Clone();
mock_receiver_ = std::make_unique<video_capture::MockReceiver>(
mojo::MakeRequest(&receiver_proxy_));
}
scoped_refptr<base::TaskRunner> main_task_runner_;
std::unique_ptr<service_manager::Connector> connector_;
std::unique_ptr<video_capture::MockReceiver> mock_receiver_;
private:
void OnSourceInfosReceived(
base::OnceClosure done_cb,
const std::vector<media::VideoCaptureDeviceInfo>& infos) {
ASSERT_FALSE(infos.empty());
video_source_provider_->GetVideoSource(infos[0].descriptor.device_id,
mojo::MakeRequest(&video_source_));
media::VideoCaptureParams requestable_settings;
ASSERT_FALSE(infos[0].supported_formats.empty());
requestable_settings.requested_format = infos[0].supported_formats[0];
requestable_settings.requested_format.frame_size = kVideoSize;
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription;
video_source_->CreatePushSubscription(
std::move(receiver_proxy_), requestable_settings,
false /*force_reopen_with_new_settings*/,
mojo::MakeRequest(&subscription_),
base::BindOnce(&WebRtcVideoCaptureSharedDeviceBrowserTest::
OnCreatePushSubscriptionCallback,
weak_factory_.GetWeakPtr(), std::move(done_cb)));
}
void OnCreatePushSubscriptionCallback(
base::OnceClosure done_cb,
video_capture::mojom::CreatePushSubscriptionResultCode result_code,
const media::VideoCaptureParams& params) {
ASSERT_EQ(video_capture::mojom::CreatePushSubscriptionResultCode::
kCreatedWithRequestedSettings,
result_code);
subscription_->Activate();
std::move(done_cb).Run();
}
base::test::ScopedFeatureList scoped_feature_list_;
video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider_;
video_capture::mojom::VideoSourceProviderPtr video_source_provider_;
video_capture::mojom::VideoSourcePtr video_source_;
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription_;
video_capture::mojom::ReceiverPtr receiver_proxy_;
base::WeakPtrFactory<WebRtcVideoCaptureSharedDeviceBrowserTest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCaptureSharedDeviceBrowserTest);
};
IN_PROC_BROWSER_TEST_F(WebRtcVideoCaptureSharedDeviceBrowserTest,
ReceiveFrameFromServiceAndInRenderer) {
Initialize();
base::RunLoop receive_frame_from_service_wait_loop;
EXPECT_CALL(*mock_receiver_, DoOnFrameReadyInBuffer(_, _, _, _))
.WillOnce(InvokeWithoutArgs([&receive_frame_from_service_wait_loop]() {
receive_frame_from_service_wait_loop.Quit();
}))
.WillRepeatedly(Return());
base::RunLoop open_device_via_service_run_loop;
OpenDeviceViaService(open_device_via_service_run_loop.QuitClosure());
open_device_via_service_run_loop.Run();
OpenDeviceInRendererAndWaitForPlaying();
receive_frame_from_service_wait_loop.Run();
}
} // namespace content
......@@ -935,6 +935,7 @@ test("content_browsertests") {
"../browser/webrtc/webrtc_video_capture_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_service_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.h",
"../browser/webui/web_ui_mojo_browsertest.cc",
......@@ -1030,6 +1031,7 @@ test("content_browsertests") {
"//services/service_manager/public/cpp",
"//services/test/echo/public/mojom",
"//services/video_capture/public/cpp",
"//services/video_capture/public/cpp:mocks",
"//services/video_capture/public/mojom:constants",
"//services/viz/privileged/interfaces",
"//services/ws/public/cpp/gpu",
......
......@@ -49,7 +49,7 @@ void BroadcastingReceiver::ClientContext::OnStartedUsingGpuDecode() {
if (on_started_using_gpu_decode_has_been_called_)
return;
on_started_using_gpu_decode_has_been_called_ = true;
client_->OnStarted();
client_->OnStartedUsingGpuDecode();
}
BroadcastingReceiver::BufferContext::BufferContext(
......@@ -156,8 +156,10 @@ int32_t BroadcastingReceiver::AddClient(mojom::ReceiverPtr client) {
if (status_ == Status::kOnStartedHasBeenCalled) {
added_client_context.OnStarted();
}
if (status_ == Status::kOnStartedUsingGpuDecodeHasBeenCalled)
if (status_ == Status::kOnStartedUsingGpuDecodeHasBeenCalled) {
added_client_context.OnStarted();
added_client_context.OnStartedUsingGpuDecode();
}
for (auto& buffer_context : buffer_contexts_) {
added_client_context.client()->OnNewBuffer(
......
......@@ -12,6 +12,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "services/video_capture/device_factory.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#if defined(OS_CHROMEOS)
#include "media/capture/video/chromeos/mojo/cros_image_capture.mojom.h"
......
......@@ -110,8 +110,6 @@ void DeviceFactoryProviderImpl::ConnectToDeviceFactory(
mojom::DeviceFactoryRequest request) {
DCHECK(service_ref_);
LazyInitializeDeviceFactory();
if (factory_bindings_.empty())
device_factory_->SetServiceRef(service_ref_->Clone());
factory_bindings_.AddBinding(device_factory_.get(), std::move(request));
}
......@@ -156,6 +154,7 @@ void DeviceFactoryProviderImpl::LazyInitializeDeviceFactory() {
&GpuDependenciesContext::CreateJpegDecodeAccelerator,
gpu_dependencies_context_->GetWeakPtr()),
gpu_dependencies_context_->GetTaskRunner()));
device_factory_->SetServiceRef(service_ref_->Clone());
}
void DeviceFactoryProviderImpl::LazyInitializeVideoSourceProvider() {
......
......@@ -6,6 +6,7 @@
#define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_DEVICE_FACTORY_H_
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#include "services/video_capture/public/mojom/producer.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
......
......@@ -5,6 +5,7 @@
#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_SOURCE_PROVIDER_H_
#define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_MOCK_VIDEO_SOURCE_PROVIDER_H_
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#include "services/video_capture/public/mojom/producer.mojom.h"
#include "services/video_capture/public/mojom/video_source_provider.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -33,6 +34,11 @@ class MockVideoSourceProvider
void AddTextureVirtualDevice(const media::VideoCaptureDeviceInfo& device_info,
video_capture::mojom::TextureVirtualDeviceRequest
virtual_device) override;
void RegisterVirtualDevicesChangedObserver(
video_capture::mojom::DevicesChangedObserverPtr observer,
bool raise_event_if_virtual_devices_already_present) override {
NOTIMPLEMENTED();
}
MOCK_METHOD1(DoGetSourceInfos, void(GetSourceInfosCallback& callback));
MOCK_METHOD2(DoGetVideoSource,
......
......@@ -9,6 +9,7 @@ mojom("mojom") {
"device.mojom",
"device_factory.mojom",
"device_factory_provider.mojom",
"devices_changed_observer.mojom",
"producer.mojom",
"receiver.mojom",
"scoped_access_permission.mojom",
......
......@@ -6,6 +6,7 @@ module video_capture.mojom;
import "media/capture/mojom/video_capture_types.mojom";
import "services/video_capture/public/mojom/device.mojom";
import "services/video_capture/public/mojom/devices_changed_observer.mojom";
import "services/video_capture/public/mojom/producer.mojom";
import "services/video_capture/public/mojom/virtual_device.mojom";
......@@ -15,10 +16,6 @@ enum DeviceAccessResultCode {
ERROR_DEVICE_NOT_FOUND
};
interface DevicesChangedObserver {
OnDevicesChanged();
};
// Enables access to a set of video capture devices.
// Typical operation is to first call GetDeviceInfos() to obtain
// information about available devices. The |device_id| of the infos can
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module video_capture.mojom;
// Callback interface for clients who wnat to get notified when virtual devices
// are added or removed.
interface DevicesChangedObserver {
OnDevicesChanged();
};
......@@ -5,6 +5,7 @@
module video_capture.mojom;
import "media/capture/mojom/video_capture_types.mojom";
import "services/video_capture/public/mojom/devices_changed_observer.mojom";
import "services/video_capture/public/mojom/producer.mojom";
import "services/video_capture/public/mojom/video_source.mojom";
import "services/video_capture/public/mojom/virtual_device.mojom";
......@@ -41,4 +42,12 @@ interface VideoSourceProvider {
AddTextureVirtualDevice(
media.mojom.VideoCaptureDeviceInfo device_info,
TextureVirtualDevice& virtual_device);
// Registered observers will get notified whenever a virtual device is added
// or removed. Note: Changes to non-virtual devices are currently being
// monitored outside the video capture service, and therefore the service
// does not offer such monitoring.
RegisterVirtualDevicesChangedObserver(
DevicesChangedObserver observer,
bool raise_event_if_virtual_devices_already_present);
};
......@@ -6,6 +6,7 @@
#define SERVICES_VIDEO_CAPTURE_TEST_MOCK_DEVICES_CHANGED_OBSERVER_H_
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace video_capture {
......
......@@ -64,6 +64,13 @@ void VideoSourceProviderImpl::AddTextureVirtualDevice(
std::move(virtual_device));
}
void VideoSourceProviderImpl::RegisterVirtualDevicesChangedObserver(
mojom::DevicesChangedObserverPtr observer,
bool raise_event_if_virtual_devices_already_present) {
device_factory_->RegisterVirtualDevicesChangedObserver(
std::move(observer), raise_event_if_virtual_devices_already_present);
}
void VideoSourceProviderImpl::OnVideoSourceLastClientDisconnected(
const std::string& device_id) {
sources_.erase(device_id);
......
......@@ -34,6 +34,9 @@ class VideoSourceProviderImpl : public mojom::VideoSourceProvider {
void AddTextureVirtualDevice(
const media::VideoCaptureDeviceInfo& device_info,
mojom::TextureVirtualDeviceRequest virtual_device) override;
void RegisterVirtualDevicesChangedObserver(
mojom::DevicesChangedObserverPtr observer,
bool raise_event_if_virtual_devices_already_present) override;
private:
void OnVideoSourceLastClientDisconnected(const std::string& device_id);
......
......@@ -12,6 +12,7 @@
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "services/video_capture/device_factory.h"
#include "services/video_capture/public/mojom/device.mojom.h"
#include "services/video_capture/public/mojom/devices_changed_observer.mojom.h"
#include "services/video_capture/public/mojom/virtual_device.mojom.h"
#if defined(OS_CHROMEOS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment