Commit 00025a37 authored by Christian Fremerey's avatar Christian Fremerey Committed by Commit Bot

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

This is a reland of 86e7aa88

Revert was due to flaky test failures on MacOS 10.12.
The flakiness already existed before this CL.
The flaky test has been disabled.
https://chromium-review.googlesource.com/c/chromium/src/+/1501213

This reland is identical to the original attempt.

TBR=emircan@chromium.org, meacer@chromium.org

Original change's description:
> [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: Mustafa Emre Acer <meacer@chromium.org>
> Reviewed-by: Emircan Uysaler <emircan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#637405}

Bug: 783442
Change-Id: I7dca38334bc78e400daa311fa0444173add9548d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1504230
Commit-Queue: Christian Fremerey <chfremer@chromium.org>
Reviewed-by: default avatarMustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatarChristian Fremerey <chfremer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#637873}
parent fb96126c
......@@ -1492,8 +1492,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,18 +3,28 @@
// 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,
// 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)));
}
......@@ -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,7 +15,9 @@ namespace content {
// service.
class ServiceLaunchedVideoCaptureDevice : public LaunchedVideoCaptureDevice {
public:
ServiceLaunchedVideoCaptureDevice(video_capture::mojom::DevicePtr device,
ServiceLaunchedVideoCaptureDevice(
video_capture::mojom::VideoSourcePtr source,
video_capture::mojom::PushVideoStreamSubscriptionPtr subscription,
base::OnceClosure connection_lost_cb);
~ServiceLaunchedVideoCaptureDevice() override;
......@@ -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