Reland "[Video Capture] Switch usage in Chromium Browser process to the new multi-client API"
This is a reland of 86e7aa883c95d551a450f71dc346fca4e31ea672
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.
[email protected], [email protected]
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 <[email protected]>
> Reviewed-by: Mustafa Emre Acer <[email protected]>
> Reviewed-by: Emircan Uysaler <[email protected]>
> 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 <[email protected]>
Reviewed-by: Mustafa Emre Acer <[email protected]>
Reviewed-by: Christian Fremerey <[email protected]>
Cr-Commit-Position: refs/heads/master@{#637873}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index e607da8..e044abc 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1492,8 +1492,8 @@
"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",
diff --git a/content/browser/renderer_host/media/ref_counted_video_capture_factory.cc b/content/browser/renderer_host/media/ref_counted_video_capture_factory.cc
deleted file mode 100644
index 0f56ad4d..0000000
--- a/content/browser/renderer_host/media/ref_counted_video_capture_factory.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 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 "content/browser/renderer_host/media/ref_counted_video_capture_factory.h"
-
-namespace content {
-
-RefCountedVideoCaptureFactory::RefCountedVideoCaptureFactory(
- video_capture::mojom::DeviceFactoryPtr device_factory,
- video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
- base::OnceClosure destruction_cb)
- : device_factory_(std::move(device_factory)),
- device_factory_provider_(std::move(device_factory_provider)),
- destruction_cb_(std::move(destruction_cb)),
- weak_ptr_factory_(this) {}
-
-RefCountedVideoCaptureFactory::~RefCountedVideoCaptureFactory() {
- std::move(destruction_cb_).Run();
-}
-
-base::WeakPtr<RefCountedVideoCaptureFactory>
-RefCountedVideoCaptureFactory::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void RefCountedVideoCaptureFactory::ShutdownServiceAsap() {
- device_factory_provider_->ShutdownServiceAsap();
-}
-
-void RefCountedVideoCaptureFactory::ReleaseFactoryForTesting() {
- device_factory_.reset();
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/media/ref_counted_video_capture_factory.h b/content/browser/renderer_host/media/ref_counted_video_capture_factory.h
deleted file mode 100644
index 670e6cb..0000000
--- a/content/browser/renderer_host/media/ref_counted_video_capture_factory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 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.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_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"
-
-namespace content {
-
-// Enables ref-counted shared ownership of a
-// video_capture::mojom::DeviceFactoryPtr.
-// 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> {
- public:
- RefCountedVideoCaptureFactory(
- video_capture::mojom::DeviceFactoryPtr device_factory,
- video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
- base::OnceClosure destruction_cb);
-
- base::WeakPtr<RefCountedVideoCaptureFactory> GetWeakPtr();
-
- const video_capture::mojom::DeviceFactoryPtr& device_factory() {
- return device_factory_;
- }
-
- void ShutdownServiceAsap();
-
- void ReleaseFactoryForTesting();
-
- private:
- friend class base::RefCounted<RefCountedVideoCaptureFactory>;
- ~RefCountedVideoCaptureFactory();
-
- video_capture::mojom::DeviceFactoryPtr device_factory_;
- video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider_;
- base::OnceClosure destruction_cb_;
- base::WeakPtrFactory<RefCountedVideoCaptureFactory> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedVideoCaptureFactory);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_CAPTURE_FACTORY_H_
diff --git a/content/browser/renderer_host/media/ref_counted_video_source_provider.cc b/content/browser/renderer_host/media/ref_counted_video_source_provider.cc
new file mode 100644
index 0000000..4414c7c
--- /dev/null
+++ b/content/browser/renderer_host/media/ref_counted_video_source_provider.cc
@@ -0,0 +1,35 @@
+// Copyright 2017 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 "content/browser/renderer_host/media/ref_counted_video_source_provider.h"
+
+namespace content {
+
+RefCountedVideoSourceProvider::RefCountedVideoSourceProvider(
+ video_capture::mojom::VideoSourceProviderPtr source_provider,
+ video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
+ base::OnceClosure destruction_cb)
+ : source_provider_(std::move(source_provider)),
+ device_factory_provider_(std::move(device_factory_provider)),
+ destruction_cb_(std::move(destruction_cb)),
+ weak_ptr_factory_(this) {}
+
+RefCountedVideoSourceProvider::~RefCountedVideoSourceProvider() {
+ std::move(destruction_cb_).Run();
+}
+
+base::WeakPtr<RefCountedVideoSourceProvider>
+RefCountedVideoSourceProvider::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
+void RefCountedVideoSourceProvider::ShutdownServiceAsap() {
+ device_factory_provider_->ShutdownServiceAsap();
+}
+
+void RefCountedVideoSourceProvider::ReleaseProviderForTesting() {
+ source_provider_.reset();
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/media/ref_counted_video_source_provider.h b/content/browser/renderer_host/media/ref_counted_video_source_provider.h
new file mode 100644
index 0000000..cb6320c
--- /dev/null
+++ b/content/browser/renderer_host/media/ref_counted_video_source_provider.h
@@ -0,0 +1,51 @@
+// Copyright 2017 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.
+
+#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_provider.mojom.h"
+#include "services/video_capture/public/mojom/video_source_provider.mojom.h"
+
+namespace content {
+
+// Enables ref-counted shared ownership of a
+// video_capture::mojom::DeviceFactoryPtr.
+// 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 RefCountedVideoSourceProvider
+ : public base::RefCounted<RefCountedVideoSourceProvider> {
+ public:
+ RefCountedVideoSourceProvider(
+ video_capture::mojom::VideoSourceProviderPtr source_provider,
+ video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider,
+ base::OnceClosure destruction_cb);
+
+ base::WeakPtr<RefCountedVideoSourceProvider> GetWeakPtr();
+
+ const video_capture::mojom::VideoSourceProviderPtr& source_provider() {
+ return source_provider_;
+ }
+
+ void ShutdownServiceAsap();
+ void ReleaseProviderForTesting();
+
+ private:
+ friend class base::RefCounted<RefCountedVideoSourceProvider>;
+ ~RefCountedVideoSourceProvider();
+
+ video_capture::mojom::VideoSourceProviderPtr source_provider_;
+ video_capture::mojom::DeviceFactoryProviderPtr device_factory_provider_;
+ base::OnceClosure destruction_cb_;
+ base::WeakPtrFactory<RefCountedVideoSourceProvider> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedVideoSourceProvider);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_REF_COUNTED_VIDEO_SOURCE_PROVIDER_H_
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.cc b/content/browser/renderer_host/media/service_launched_video_capture_device.cc
index 947804866..c52a2c9 100644
--- a/content/browser/renderer_host/media/service_launched_video_capture_device.cc
+++ b/content/browser/renderer_host/media/service_launched_video_capture_device.cc
@@ -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 @@
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 @@
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 @@
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::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();
}
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.h b/content/browser/renderer_host/media/service_launched_video_capture_device.h
index 86764d76..b36917f 100644
--- a/content/browser/renderer_host/media/service_launched_video_capture_device.h
+++ b/content/browser/renderer_host/media/service_launched_video_capture_device.h
@@ -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 @@
// 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 @@
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 @@
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_;
};
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
index a37f0b2..87aca61 100644
--- a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
+++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
@@ -20,37 +20,26 @@
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 @@
} // 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 @@
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 @@
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 @@
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 @@
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
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.h b/content/browser/renderer_host/media/service_video_capture_device_launcher.h
index afe0b95..2936448 100644
--- a/content/browser/renderer_host/media/service_video_capture_device_launcher.h
+++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.h
@@ -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 @@
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 @@
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_;
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
index d7eaf68..e7d641b6 100644
--- a/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
+++ b/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
@@ -9,17 +9,20 @@
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/threading/thread.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/service_launched_video_capture_device.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/video_capture/public/cpp/mock_device_factory.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/video_capture/public/cpp/mock_push_subscription.h"
+#include "services/video_capture/public/cpp/mock_video_source.h"
+#include "services/video_capture/public/cpp/mock_video_source_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::_;
using testing::Invoke;
using testing::InvokeWithoutArgs;
-using testing::_;
namespace content {
@@ -46,46 +49,87 @@
ServiceVideoCaptureDeviceLauncherTest() {}
~ServiceVideoCaptureDeviceLauncherTest() override {}
+ void CloseSourceBinding() { source_binding_.reset(); }
+
+ void CloseSubscriptionBindings() {
+ subscription_bindings_.CloseAllBindings();
+ }
+
protected:
void SetUp() override {
- video_capture::mojom::DeviceFactoryPtr device_factory;
- factory_binding_ =
- std::make_unique<mojo::Binding<video_capture::mojom::DeviceFactory>>(
- &mock_device_factory_, mojo::MakeRequest(&device_factory));
- factory_delegate_ = base::MakeRefCounted<RefCountedVideoCaptureFactory>(
- std::move(device_factory),
+ source_provider_binding_ = std::make_unique<
+ mojo::Binding<video_capture::mojom::VideoSourceProvider>>(
+ &mock_source_provider_, mojo::MakeRequest(&source_provider_));
+ service_connection_ = base::MakeRefCounted<RefCountedVideoSourceProvider>(
+ std::move(source_provider_),
video_capture::mojom::DeviceFactoryProviderPtr(),
release_connection_cb_.Get());
launcher_ = std::make_unique<ServiceVideoCaptureDeviceLauncher>(
connect_to_device_factory_cb_.Get());
- launcher_has_connected_to_device_factory_ = false;
- launcher_has_released_device_factory_ = false;
+ launcher_has_connected_to_source_provider_ = false;
+ launcher_has_released_source_provider_ = false;
ON_CALL(connect_to_device_factory_cb_, Run(_))
.WillByDefault(Invoke(
- [this](scoped_refptr<RefCountedVideoCaptureFactory>* out_factory) {
- launcher_has_connected_to_device_factory_ = true;
- *out_factory = factory_delegate_;
+ [this](scoped_refptr<RefCountedVideoSourceProvider>* out_provider) {
+ launcher_has_connected_to_source_provider_ = true;
+ *out_provider = service_connection_;
}));
ON_CALL(release_connection_cb_, Run())
.WillByDefault(InvokeWithoutArgs([this]() {
- launcher_has_released_device_factory_ = true;
+ launcher_has_released_source_provider_ = true;
wait_for_release_connection_cb_.Quit();
}));
+
+ ON_CALL(mock_source_provider_, DoGetVideoSource(kStubDeviceId, _))
+ .WillByDefault(Invoke(
+ [this](const std::string& device_id,
+ video_capture::mojom::VideoSourceRequest* source_request) {
+ source_binding_ = std::make_unique<
+ mojo::Binding<video_capture::mojom::VideoSource>>(
+ &mock_source_, std::move(*source_request));
+ }));
+
+ ON_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _))
+ .WillByDefault(Invoke(
+ [this](video_capture::mojom::ReceiverPtr& subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ bool force_reopen_with_new_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest&
+ subscription,
+ video_capture::mojom::VideoSource::
+ CreatePushSubscriptionCallback& callback) {
+ subscription_bindings_.AddBinding(&mock_subscription_,
+ std::move(subscription));
+ std::move(callback).Run(
+ video_capture::mojom::CreatePushSubscriptionResultCode::
+ kCreatedWithRequestedSettings,
+ requested_settings);
+ }));
}
void TearDown() override {}
void RunLaunchingDeviceIsAbortedTest(
- video_capture::mojom::DeviceAccessResultCode service_result_code);
+ video_capture::mojom::CreatePushSubscriptionResultCode
+ service_result_code);
+ void RunConnectionLostAfterSuccessfulStartTest(
+ base::OnceClosure close_connection_cb);
TestBrowserThreadBundle thread_bundle_;
- video_capture::MockDeviceFactory mock_device_factory_;
MockVideoCaptureDeviceLauncherCallbacks mock_callbacks_;
- std::unique_ptr<mojo::Binding<video_capture::mojom::DeviceFactory>>
- factory_binding_;
+ video_capture::mojom::VideoSourceProviderPtr source_provider_;
+ video_capture::MockVideoSourceProvider mock_source_provider_;
+ std::unique_ptr<mojo::Binding<video_capture::mojom::VideoSourceProvider>>
+ source_provider_binding_;
+ video_capture::MockVideoSource mock_source_;
+ std::unique_ptr<mojo::Binding<video_capture::mojom::VideoSource>>
+ source_binding_;
+ video_capture::MockPushSubcription mock_subscription_;
+ mojo::BindingSet<video_capture::mojom::PushVideoStreamSubscription>
+ subscription_bindings_;
std::unique_ptr<ServiceVideoCaptureDeviceLauncher> launcher_;
base::MockCallback<base::OnceClosure> connection_lost_cb_;
base::MockCallback<base::OnceClosure> done_cb_;
@@ -93,11 +137,11 @@
ServiceVideoCaptureDeviceLauncher::ConnectToDeviceFactoryCB>
connect_to_device_factory_cb_;
base::MockCallback<base::OnceClosure> release_connection_cb_;
- // |factory_delegate_| needs to go below |release_connection_cb_|, because its
- // destructor will call |release_connection_cb_|.
- scoped_refptr<RefCountedVideoCaptureFactory> factory_delegate_;
- bool launcher_has_connected_to_device_factory_;
- bool launcher_has_released_device_factory_;
+ // |service_connection_| needs to go below |release_connection_cb_|, because
+ // its destructor will call |release_connection_cb_|.
+ scoped_refptr<RefCountedVideoSourceProvider> service_connection_;
+ bool launcher_has_connected_to_source_provider_;
+ bool launcher_has_released_source_provider_;
base::RunLoop wait_for_release_connection_cb_;
private:
@@ -105,26 +149,6 @@
};
TEST_F(ServiceVideoCaptureDeviceLauncherTest, LaunchingDeviceSucceeds) {
- EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
- .WillOnce(Invoke([](const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::
- CreateDeviceCallback& callback) {
- // Note: We must keep |device_request| alive at least until we have
- // sent out the callback. Otherwise, |launcher_| may interpret this
- // as the connection having been lost before receiving the callback.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](video_capture::mojom::DeviceRequest device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback
- callback) {
- std::move(callback).Run(
- video_capture::mojom::DeviceAccessResultCode::SUCCESS);
- },
- std::move(*device_request), std::move(callback)));
- }));
-
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(1);
EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
EXPECT_CALL(mock_callbacks_, OnDeviceLaunchFailed(_)).Times(0);
@@ -142,55 +166,64 @@
wait_for_done_cb.Run();
launcher_.reset();
- factory_delegate_.reset();
+ service_connection_.reset();
wait_for_release_connection_cb_.Run();
- EXPECT_TRUE(launcher_has_connected_to_device_factory_);
- EXPECT_TRUE(launcher_has_released_device_factory_);
+ EXPECT_TRUE(launcher_has_connected_to_source_provider_);
+ EXPECT_TRUE(launcher_has_released_source_provider_);
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
LaunchingDeviceIsAbortedBeforeServiceRespondsWithSuccess) {
RunLaunchingDeviceIsAbortedTest(
- video_capture::mojom::DeviceAccessResultCode::SUCCESS);
+ video_capture::mojom::CreatePushSubscriptionResultCode::
+ kCreatedWithRequestedSettings);
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
LaunchingDeviceIsAbortedBeforeServiceRespondsWithNotFound) {
RunLaunchingDeviceIsAbortedTest(
- video_capture::mojom::DeviceAccessResultCode::ERROR_DEVICE_NOT_FOUND);
+ video_capture::mojom::CreatePushSubscriptionResultCode::
+ kCreatedWithDifferentSettings);
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
LaunchingDeviceIsAbortedBeforeServiceRespondsWithNotInitialized) {
RunLaunchingDeviceIsAbortedTest(
- video_capture::mojom::DeviceAccessResultCode::NOT_INITIALIZED);
+ video_capture::mojom::CreatePushSubscriptionResultCode::kFailed);
}
void ServiceVideoCaptureDeviceLauncherTest::RunLaunchingDeviceIsAbortedTest(
- video_capture::mojom::DeviceAccessResultCode service_result_code) {
+ video_capture::mojom::CreatePushSubscriptionResultCode
+ service_result_code) {
base::RunLoop step_1_run_loop;
base::RunLoop step_2_run_loop;
- base::OnceClosure create_device_success_answer_cb;
- EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
- .WillOnce(
- Invoke([&create_device_success_answer_cb, &step_1_run_loop,
- service_result_code](
- const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback&
- callback) {
+ base::OnceClosure create_push_subscription_success_answer_cb;
+ EXPECT_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _))
+ .WillOnce(Invoke(
+ [&create_push_subscription_success_answer_cb, &step_1_run_loop,
+ service_result_code](
+ video_capture::mojom::ReceiverPtr& subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ bool force_reopen_with_new_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest&
+ subscription,
+ video_capture::mojom::VideoSource::CreatePushSubscriptionCallback&
+ callback) {
// Prepare the callback, but save it for now instead of invoking it.
- create_device_success_answer_cb = base::BindOnce(
- [](video_capture::mojom::DeviceRequest device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback
- callback,
- video_capture::mojom::DeviceAccessResultCode
+ create_push_subscription_success_answer_cb = base::BindOnce(
+ [](const media::VideoCaptureParams& requested_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest
+ subscription,
+ video_capture::mojom::VideoSource::
+ CreatePushSubscriptionCallback callback,
+ video_capture::mojom::CreatePushSubscriptionResultCode
service_result_code) {
- std::move(callback).Run(service_result_code);
+ std::move(callback).Run(service_result_code,
+ requested_settings);
},
- std::move(*device_request), std::move(callback),
- service_result_code);
+ requested_settings, std::move(subscription),
+ std::move(callback), service_result_code);
step_1_run_loop.Quit();
}));
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
@@ -209,39 +242,46 @@
step_1_run_loop.Run();
launcher_->AbortLaunch();
- std::move(create_device_success_answer_cb).Run();
+ std::move(create_push_subscription_success_answer_cb).Run();
step_2_run_loop.Run();
- factory_delegate_.reset();
+ service_connection_.reset();
- EXPECT_TRUE(launcher_has_connected_to_device_factory_);
- EXPECT_TRUE(launcher_has_released_device_factory_);
+ EXPECT_TRUE(launcher_has_connected_to_source_provider_);
+ EXPECT_TRUE(launcher_has_released_source_provider_);
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
LaunchingDeviceFailsBecauseDeviceNotFound) {
base::RunLoop run_loop;
- EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
- .WillOnce(
- Invoke([](const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback&
- callback) {
- // Note: We must keep |device_request| alive at least until we have
- // sent out the callback. Otherwise, |launcher_| may interpret this
- // as the connection having been lost before receiving the callback.
+ EXPECT_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _))
+ .WillOnce(Invoke(
+ [](video_capture::mojom::ReceiverPtr& subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ bool force_reopen_with_new_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest&
+ subscription,
+ video_capture::mojom::VideoSource::CreatePushSubscriptionCallback&
+ callback) {
+ // Note: We post this to the end of the message queue to make it
+ // asynchronous.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
- [](video_capture::mojom::DeviceRequest device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback
- callback) {
+ [](video_capture::mojom::ReceiverPtr subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest
+ subscription,
+ video_capture::mojom::VideoSource::
+ CreatePushSubscriptionCallback callback) {
std::move(callback).Run(
- video_capture::mojom::DeviceAccessResultCode::
- ERROR_DEVICE_NOT_FOUND);
+ video_capture::mojom::
+ CreatePushSubscriptionResultCode::kFailed,
+ requested_settings);
},
- std::move(*device_request), std::move(callback)));
+ std::move(subscriber), requested_settings,
+ std::move(subscription), std::move(callback)));
}));
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
@@ -264,7 +304,7 @@
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
- LaunchingDeviceFailsBecauseFactoryIsUnbound) {
+ LaunchingDeviceFailsBecauseSourceProviderIsUnbound) {
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
@@ -276,7 +316,7 @@
}));
// Exercise
- factory_delegate_->ReleaseFactoryForTesting();
+ service_connection_->ReleaseProviderForTesting();
launcher_->LaunchDeviceAsync(kStubDeviceId, blink::MEDIA_DEVICE_VIDEO_CAPTURE,
kArbitraryParams, kNullReceiver,
@@ -290,18 +330,22 @@
LaunchingDeviceFailsBecauseConnectionLostWhileLaunching) {
base::RunLoop run_loop;
- video_capture::mojom::DeviceFactory::CreateDeviceCallback create_device_cb;
- EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
- .WillOnce(
- Invoke([&create_device_cb](
- const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback&
- callback) {
+ video_capture::mojom::VideoSource::CreatePushSubscriptionCallback
+ create_subscription_cb;
+ EXPECT_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _))
+ .WillOnce(Invoke(
+ [&create_subscription_cb](
+ video_capture::mojom::ReceiverPtr& subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ bool force_reopen_with_new_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest&
+ subscription,
+ video_capture::mojom::VideoSource::CreatePushSubscriptionCallback&
+ callback) {
// Simulate connection lost by not invoking |callback| and releasing
- // |device_request|. We have to save |callback| and invoke it later
+ // |subscription|. We have to save |callback| and invoke it later
// to avoid hitting a DCHECK.
- create_device_cb = std::move(callback);
+ create_subscription_cb = std::move(callback);
}));
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_)).Times(0);
EXPECT_CALL(mock_callbacks_, OnDeviceLaunchAborted()).Times(0);
@@ -321,36 +365,35 @@
run_loop.Run();
- // Cut the connection to the factory, so that the outstanding
- // |create_device_cb| will be dropped.
- factory_binding_.reset();
+ // Cleanup
+ // Cut the connection to the source, so that the outstanding
+ // |create_subscription_cb| will be dropped when we invoke it below.
+ source_binding_.reset();
// We have to invoke the callback, because not doing so triggers a DCHECK.
- const video_capture::mojom::DeviceAccessResultCode arbitrary_result_code =
- video_capture::mojom::DeviceAccessResultCode::SUCCESS;
- std::move(create_device_cb).Run(arbitrary_result_code);
+ const video_capture::mojom::CreatePushSubscriptionResultCode
+ arbitrary_result_code = video_capture::mojom::
+ CreatePushSubscriptionResultCode::kCreatedWithRequestedSettings;
+ std::move(create_subscription_cb)
+ .Run(arbitrary_result_code, kArbitraryParams);
}
TEST_F(ServiceVideoCaptureDeviceLauncherTest,
- ConnectionLostAfterSuccessfulLaunch) {
- video_capture::mojom::DeviceRequest device_request_owned_by_service;
- EXPECT_CALL(mock_device_factory_, DoCreateDevice(kStubDeviceId, _, _))
- .WillOnce(Invoke([&device_request_owned_by_service](
- const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::
- CreateDeviceCallback& callback) {
- // The service holds on to the |device_request|.
- device_request_owned_by_service = std::move(*device_request);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](video_capture::mojom::DeviceFactory::CreateDeviceCallback
- callback) {
- std::move(callback).Run(
- video_capture::mojom::DeviceAccessResultCode::SUCCESS);
- },
- std::move(callback)));
- }));
+ ConnectionToSubscriptionLostAfterSuccessfulLaunch) {
+ RunConnectionLostAfterSuccessfulStartTest(
+ base::BindOnce(&ServiceVideoCaptureDeviceLauncherTest::CloseSourceBinding,
+ base::Unretained(this)));
+}
+
+TEST_F(ServiceVideoCaptureDeviceLauncherTest,
+ ConnectionToSourceLostAfterSuccessfulLaunch) {
+ RunConnectionLostAfterSuccessfulStartTest(base::BindOnce(
+ &ServiceVideoCaptureDeviceLauncherTest::CloseSubscriptionBindings,
+ base::Unretained(this)));
+}
+
+void ServiceVideoCaptureDeviceLauncherTest::
+ RunConnectionLostAfterSuccessfulStartTest(
+ base::OnceClosure close_connection_cb) {
std::unique_ptr<LaunchedVideoCaptureDevice> launched_device;
EXPECT_CALL(mock_callbacks_, DoOnDeviceLaunched(_))
.WillOnce(
@@ -376,14 +419,14 @@
step_2_run_loop.Quit();
}));
// Exercise step 2: The service cuts/loses the connection
- device_request_owned_by_service = nullptr;
+ std::move(close_connection_cb).Run();
step_2_run_loop.Run();
launcher_.reset();
- factory_delegate_.reset();
+ service_connection_.reset();
wait_for_release_connection_cb_.Run();
- EXPECT_TRUE(launcher_has_connected_to_device_factory_);
- EXPECT_TRUE(launcher_has_released_device_factory_);
+ EXPECT_TRUE(launcher_has_connected_to_source_provider_);
+ EXPECT_TRUE(launcher_has_released_source_provider_);
}
} // namespace content
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.cc b/content/browser/renderer_host/media/service_video_capture_provider.cc
index fa741990..55c56ec 100644
--- a/content/browser/renderer_host/media/service_video_capture_provider.cc
+++ b/content/browser/renderer_host/media/service_video_capture_provider.cc
@@ -59,7 +59,7 @@
: 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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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::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 @@
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 @@
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);
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.h b/content/browser/renderer_host/media/service_video_capture_provider.h
index 55fb590..ed95c61 100644
--- a/content/browser/renderer_host/media/service_video_capture_provider.h
+++ b/content/browser/renderer_host/media/service_video_capture_provider.h
@@ -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 @@
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_;
diff --git a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
index 7220d9d..6246579 100644
--- a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
+++ b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
@@ -12,12 +12,15 @@
#include "content/public/browser/video_capture_device_launcher.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
-#include "services/video_capture/public/cpp/mock_device_factory.h"
#include "services/video_capture/public/cpp/mock_device_factory_provider.h"
+#include "services/video_capture/public/cpp/mock_push_subscription.h"
+#include "services/video_capture/public/cpp/mock_video_source.h"
+#include "services/video_capture/public/cpp/mock_video_source_provider.h"
#include "services/video_capture/public/mojom/constants.mojom.h"
#include "services/video_capture/public/mojom/producer.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -101,7 +104,7 @@
service_manager::mojom::kServiceName)),
factory_provider_binding_(&mock_device_factory_provider_),
factory_provider_is_bound_(false),
- device_factory_binding_(&mock_device_factory_) {}
+ source_provider_binding_(&mock_source_provider_) {}
~ServiceVideoCaptureProviderTest() override {}
protected:
@@ -127,14 +130,45 @@
},
&factory_provider_is_bound_));
}));
- ON_CALL(mock_device_factory_provider_, DoConnectToDeviceFactory(_))
- .WillByDefault(
- Invoke([this](video_capture::mojom::DeviceFactoryRequest& request) {
- if (device_factory_binding_.is_bound())
- device_factory_binding_.Close();
- device_factory_binding_.Bind(std::move(request));
+ ON_CALL(mock_device_factory_provider_, DoConnectToVideoSourceProvider(_))
+ .WillByDefault(Invoke(
+ [this](video_capture::mojom::VideoSourceProviderRequest& request) {
+ if (source_provider_binding_.is_bound())
+ source_provider_binding_.Close();
+ source_provider_binding_.Bind(std::move(request));
wait_for_connection_to_service_.Quit();
}));
+
+ ON_CALL(mock_source_provider_, DoGetSourceInfos(_))
+ .WillByDefault(Invoke([](video_capture::mojom::VideoSourceProvider::
+ GetSourceInfosCallback& callback) {
+ std::vector<media::VideoCaptureDeviceInfo> arbitrarily_empty_results;
+ base::ResetAndReturn(&callback).Run(arbitrarily_empty_results);
+ }));
+
+ ON_CALL(mock_source_provider_, DoGetVideoSource(_, _))
+ .WillByDefault(
+ Invoke([this](const std::string& device_id,
+ video_capture::mojom::VideoSourceRequest* request) {
+ source_bindings_.AddBinding(&mock_source_, std::move(*request));
+ }));
+
+ ON_CALL(mock_source_, DoCreatePushSubscription(_, _, _, _, _))
+ .WillByDefault(Invoke(
+ [this](video_capture::mojom::ReceiverPtr& subscriber,
+ const media::VideoCaptureParams& requested_settings,
+ bool force_reopen_with_new_settings,
+ video_capture::mojom::PushVideoStreamSubscriptionRequest&
+ subscription,
+ video_capture::mojom::VideoSource::
+ CreatePushSubscriptionCallback& callback) {
+ subscription_bindings_.AddBinding(&mock_subscription_,
+ std::move(subscription));
+ std::move(callback).Run(
+ video_capture::mojom::CreatePushSubscriptionResultCode::
+ kCreatedWithRequestedSettings,
+ requested_settings);
+ }));
}
void TearDown() override {}
@@ -147,12 +181,18 @@
mojo::Binding<video_capture::mojom::DeviceFactoryProvider>
factory_provider_binding_;
bool factory_provider_is_bound_;
- video_capture::MockDeviceFactory mock_device_factory_;
- mojo::Binding<video_capture::mojom::DeviceFactory> device_factory_binding_;
+ video_capture::MockVideoSourceProvider mock_source_provider_;
+ mojo::Binding<video_capture::mojom::VideoSourceProvider>
+ source_provider_binding_;
+ video_capture::MockVideoSource mock_source_;
+ mojo::BindingSet<video_capture::mojom::VideoSource> source_bindings_;
+ video_capture::MockPushSubcription mock_subscription_;
+ mojo::BindingSet<video_capture::mojom::PushVideoStreamSubscription>
+ subscription_bindings_;
std::unique_ptr<ServiceVideoCaptureProvider> provider_;
base::MockCallback<VideoCaptureProvider::GetDeviceInfosCallback> results_cb_;
base::MockCallback<
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback>
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback>
service_cb_;
base::RunLoop wait_for_connection_to_service_;
@@ -167,14 +207,14 @@
GetDeviceInfosAsyncInvokesCallbackWhenLosingConnection) {
base::RunLoop run_loop;
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback
callback_to_be_called_by_service;
base::RunLoop wait_for_call_to_arrive_at_service;
- EXPECT_CALL(mock_device_factory_, DoGetDeviceInfos(_))
+ EXPECT_CALL(mock_source_provider_, DoGetSourceInfos(_))
.WillOnce(Invoke(
[&callback_to_be_called_by_service,
&wait_for_call_to_arrive_at_service](
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback&
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback&
callback) {
// Hold on to the callback so we can drop it later.
callback_to_be_called_by_service = std::move(callback);
@@ -194,7 +234,7 @@
wait_for_call_to_arrive_at_service.Run();
// Simulate that the service goes down by cutting the connections.
- device_factory_binding_.Close();
+ source_provider_binding_.Close();
factory_provider_binding_.Close();
wait_for_callback_from_service.Run();
@@ -205,14 +245,14 @@
TEST_F(ServiceVideoCaptureProviderTest,
ClosesServiceConnectionAfterGetDeviceInfos) {
// Setup part 1
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback
callback_to_be_called_by_service;
base::RunLoop wait_for_call_to_arrive_at_service;
- EXPECT_CALL(mock_device_factory_, DoGetDeviceInfos(_))
+ EXPECT_CALL(mock_source_provider_, DoGetSourceInfos(_))
.WillOnce(Invoke(
[&callback_to_be_called_by_service,
&wait_for_call_to_arrive_at_service](
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback&
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback&
callback) {
// Hold on to the callback so we can drop it later.
callback_to_be_called_by_service = std::move(callback);
@@ -225,11 +265,11 @@
// Setup part 2: Now that the connection to the service is established, we can
// listen for disconnects.
- base::RunLoop wait_for_connection_to_device_factory_to_close;
+ base::RunLoop wait_for_connection_to_source_provider_to_close;
base::RunLoop wait_for_connection_to_device_factory_provider_to_close;
- device_factory_binding_.set_connection_error_handler(
+ source_provider_binding_.set_connection_error_handler(
base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); },
- &wait_for_connection_to_device_factory_to_close));
+ &wait_for_connection_to_source_provider_to_close));
factory_provider_binding_.set_connection_error_handler(
base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); },
&wait_for_connection_to_device_factory_provider_to_close));
@@ -240,7 +280,7 @@
.Run(arbitrarily_empty_results);
// Verification: Expect |provider_| to close the connection to the service.
- wait_for_connection_to_device_factory_to_close.Run();
+ wait_for_connection_to_source_provider_to_close.Run();
if (factory_provider_is_bound_) {
wait_for_connection_to_device_factory_provider_to_close.Run();
}
@@ -252,21 +292,6 @@
// soon as the last VideoCaptureDeviceLauncher instance is released.
TEST_F(ServiceVideoCaptureProviderTest,
KeepsServiceConnectionWhileDeviceLauncherAlive) {
- ON_CALL(mock_device_factory_, DoGetDeviceInfos(_))
- .WillByDefault(Invoke([](video_capture::mojom::DeviceFactory::
- GetDeviceInfosCallback& callback) {
- std::vector<media::VideoCaptureDeviceInfo> arbitrarily_empty_results;
- base::ResetAndReturn(&callback).Run(arbitrarily_empty_results);
- }));
- ON_CALL(mock_device_factory_, DoCreateDevice(_, _, _))
- .WillByDefault(
- Invoke([](const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- video_capture::mojom::DeviceFactory::CreateDeviceCallback&
- callback) {
- base::ResetAndReturn(&callback).Run(
- video_capture::mojom::DeviceAccessResultCode::SUCCESS);
- }));
MockVideoCaptureDeviceLauncherCallbacks mock_callbacks;
// Exercise part 1: Create a device launcher and hold on to it.
@@ -281,7 +306,7 @@
// Monitor if connection gets closed
bool connection_has_been_closed = false;
- device_factory_binding_.set_connection_error_handler(base::BindOnce(
+ source_provider_binding_.set_connection_error_handler(base::BindOnce(
[](bool* connection_has_been_closed) {
*connection_has_been_closed = true;
},
@@ -335,7 +360,7 @@
}
ASSERT_FALSE(connection_has_been_closed);
- // Exercise part 3: Release the initial device launcher.
+ // Exercise part 4: Release the initial device launcher.
device_launcher_1.reset();
{
base::RunLoop give_provider_chance_to_disconnect;
@@ -352,12 +377,12 @@
DoesNotCloseServiceConnectionWhileGetDeviceInfoResponsePending) {
// When GetDeviceInfos gets called, hold on to the callbacks, but do not
// yet invoke them.
- std::vector<video_capture::mojom::DeviceFactory::GetDeviceInfosCallback>
+ std::vector<video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback>
callbacks_to_be_called_by_service;
- ON_CALL(mock_device_factory_, DoGetDeviceInfos(_))
+ ON_CALL(mock_source_provider_, DoGetSourceInfos(_))
.WillByDefault(Invoke(
[&callbacks_to_be_called_by_service](
- video_capture::mojom::DeviceFactory::GetDeviceInfosCallback&
+ video_capture::mojom::VideoSourceProvider::GetSourceInfosCallback&
callback) {
callbacks_to_be_called_by_service.push_back(std::move(callback));
}));
@@ -377,7 +402,7 @@
// Monitor if connection gets closed
bool connection_has_been_closed = false;
- device_factory_binding_.set_connection_error_handler(base::BindOnce(
+ source_provider_binding_.set_connection_error_handler(base::BindOnce(
[](bool* connection_has_been_closed) {
*connection_has_been_closed = true;
},
diff --git a/content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h b/content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h
index f40e0f9e..591c3d7 100644
--- a/content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h
+++ b/content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h
@@ -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 {
diff --git a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
index baf2e0e..725df9a 100644
--- a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
+++ b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
@@ -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 {
diff --git a/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc b/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc
new file mode 100644
index 0000000..bdad1dd
--- /dev/null
+++ b/content/browser/webrtc/webrtc_video_capture_shared_device_browsertest.cc
@@ -0,0 +1,174 @@
+// 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