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