summaryrefslogtreecommitdiff
path: root/chromium/services/video_capture/service_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/services/video_capture/service_impl.cc')
-rw-r--r--chromium/services/video_capture/service_impl.cc192
1 files changed, 192 insertions, 0 deletions
diff --git a/chromium/services/video_capture/service_impl.cc b/chromium/services/video_capture/service_impl.cc
new file mode 100644
index 00000000000..5bf14321766
--- /dev/null
+++ b/chromium/services/video_capture/service_impl.cc
@@ -0,0 +1,192 @@
+// Copyright 2016 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 "services/video_capture/service_impl.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "build/build_config.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/video_capture/device_factory_provider_impl.h"
+#include "services/video_capture/public/mojom/constants.mojom.h"
+#include "services/video_capture/public/uma/video_capture_service_event.h"
+#include "services/video_capture/testing_controls_impl.h"
+
+#if defined(OS_CHROMEOS)
+#include "media/capture/video/chromeos/mojo/cros_image_capture.mojom.h"
+#endif // defined(OS_CHROMEOS)
+
+namespace video_capture {
+
+namespace {
+
+#if defined(OS_ANDROID)
+// On Android, we do not use automatic service shutdown, because when shutting
+// down the service, we lose caching of the supported formats, and re-querying
+// these can take several seconds on certain Android devices.
+constexpr base::Optional<base::TimeDelta> kDefaultIdleTimeout;
+#else
+constexpr base::Optional<base::TimeDelta> kDefaultIdleTimeout =
+ base::TimeDelta::FromSeconds(5);
+#endif
+
+} // namespace
+
+ServiceImpl::ServiceImpl(
+ service_manager::mojom::ServiceRequest request,
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
+ : ServiceImpl(std::move(request),
+ std::move(ui_task_runner),
+ kDefaultIdleTimeout) {}
+
+ServiceImpl::ServiceImpl(
+ service_manager::mojom::ServiceRequest request,
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
+ base::Optional<base::TimeDelta> idle_timeout)
+ : binding_(this, std::move(request)),
+ keepalive_(&binding_, idle_timeout),
+ ui_task_runner_(std::move(ui_task_runner)) {
+ keepalive_.AddObserver(this);
+}
+
+ServiceImpl::~ServiceImpl() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ keepalive_.RemoveObserver(this);
+}
+
+void ServiceImpl::SetFactoryProviderClientConnectedObserver(
+ base::RepeatingClosure observer_cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ factory_provider_client_connected_cb_ = std::move(observer_cb);
+}
+
+void ServiceImpl::SetFactoryProviderClientDisconnectedObserver(
+ base::RepeatingClosure observer_cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ factory_provider_client_disconnected_cb_ = std::move(observer_cb);
+}
+
+void ServiceImpl::SetShutdownTimeoutCancelledObserver(
+ base::RepeatingClosure observer_cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ shutdown_timeout_cancelled_cb_ = std::move(observer_cb);
+}
+
+bool ServiceImpl::HasNoContextRefs() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return keepalive_.HasNoRefs();
+}
+
+void ServiceImpl::ShutdownServiceAsap() {
+ binding_.RequestClose();
+}
+
+void ServiceImpl::OnStart() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ video_capture::uma::LogVideoCaptureServiceEvent(
+ video_capture::uma::SERVICE_STARTED);
+
+ registry_.AddInterface<mojom::DeviceFactoryProvider>(
+ // Unretained |this| is safe because |registry_| is owned by |this|.
+ base::BindRepeating(&ServiceImpl::OnDeviceFactoryProviderRequest,
+ base::Unretained(this)));
+ registry_.AddInterface<mojom::TestingControls>(
+ // Unretained |this| is safe because |registry_| is owned by |this|.
+ base::BindRepeating(&ServiceImpl::OnTestingControlsRequest,
+ base::Unretained(this)));
+
+#if defined(OS_CHROMEOS)
+ registry_.AddInterface<cros::mojom::CrosImageCapture>(base::BindRepeating(
+ &ServiceImpl::OnCrosImageCaptureRequest, base::Unretained(this)));
+#endif // defined(OS_CHROMEOS)
+
+ // Unretained |this| is safe because |factory_provider_bindings_| is owned by
+ // |this|.
+ factory_provider_bindings_.set_connection_error_handler(base::BindRepeating(
+ &ServiceImpl::OnProviderClientDisconnected, base::Unretained(this)));
+}
+
+void ServiceImpl::OnBindInterface(
+ const service_manager::BindSourceInfo& source_info,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ registry_.BindInterface(interface_name, std::move(interface_pipe));
+}
+
+bool ServiceImpl::OnServiceManagerConnectionLost() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return true;
+}
+
+void ServiceImpl::OnIdleTimeout() {
+ video_capture::uma::LogVideoCaptureServiceEvent(
+ video_capture::uma::SERVICE_SHUTTING_DOWN_BECAUSE_NO_CLIENT);
+}
+
+void ServiceImpl::OnIdleTimeoutCancelled() {
+ video_capture::uma::LogVideoCaptureServiceEvent(
+ video_capture::uma::SERVICE_SHUTDOWN_TIMEOUT_CANCELED);
+ if (shutdown_timeout_cancelled_cb_)
+ shutdown_timeout_cancelled_cb_.Run();
+}
+
+void ServiceImpl::OnDeviceFactoryProviderRequest(
+ mojom::DeviceFactoryProviderRequest request) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ LazyInitializeDeviceFactoryProvider();
+ if (factory_provider_bindings_.empty())
+ device_factory_provider_->SetServiceRef(keepalive_.CreateRef());
+ factory_provider_bindings_.AddBinding(device_factory_provider_.get(),
+ std::move(request));
+
+ if (!factory_provider_client_connected_cb_.is_null()) {
+ factory_provider_client_connected_cb_.Run();
+ }
+}
+
+void ServiceImpl::OnTestingControlsRequest(
+ mojom::TestingControlsRequest request) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ mojo::MakeStrongBinding(
+ std::make_unique<TestingControlsImpl>(keepalive_.CreateRef()),
+ std::move(request));
+}
+
+#if defined(OS_CHROMEOS)
+void ServiceImpl::OnCrosImageCaptureRequest(
+ cros::mojom::CrosImageCaptureRequest request) {
+ LazyInitializeDeviceFactoryProvider();
+ device_factory_provider_->BindCrosImageCaptureRequest(std::move(request));
+}
+#endif // defined(OS_CHROMEOS)
+
+void ServiceImpl::LazyInitializeDeviceFactoryProvider() {
+ if (device_factory_provider_)
+ return;
+
+ // Use of base::Unretained() is safe because |this| owns, and therefore
+ // outlives |device_factory_provider_|
+ device_factory_provider_ = std::make_unique<DeviceFactoryProviderImpl>(
+ ui_task_runner_, base::BindOnce(&ServiceImpl::ShutdownServiceAsap,
+ base::Unretained(this)));
+}
+
+void ServiceImpl::OnProviderClientDisconnected() {
+ // If last client has disconnected, release service ref so that service
+ // shutdown timeout starts if no other references are still alive.
+ // We keep the |device_factory_provider_| instance alive in order to avoid
+ // losing state that would be expensive to reinitialize, e.g. having
+ // already enumerated the available devices.
+ if (factory_provider_bindings_.empty())
+ device_factory_provider_->SetServiceRef(nullptr);
+
+ if (!factory_provider_client_disconnected_cb_.is_null()) {
+ factory_provider_client_disconnected_cb_.Run();
+ }
+}
+
+} // namespace video_capture