summaryrefslogtreecommitdiff
path: root/chromium/components/arc/arc_bridge_host_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/arc/arc_bridge_host_impl.cc')
-rw-r--r--chromium/components/arc/arc_bridge_host_impl.cc247
1 files changed, 247 insertions, 0 deletions
diff --git a/chromium/components/arc/arc_bridge_host_impl.cc b/chromium/components/arc/arc_bridge_host_impl.cc
new file mode 100644
index 00000000000..94e558985ae
--- /dev/null
+++ b/chromium/components/arc/arc_bridge_host_impl.cc
@@ -0,0 +1,247 @@
+// 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 "components/arc/arc_bridge_host_impl.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/instance_holder.h"
+
+namespace arc {
+
+// Thin interface to wrap InterfacePtr<T> with type erasure.
+class ArcBridgeHostImpl::MojoChannel {
+ public:
+ virtual ~MojoChannel() = default;
+
+ protected:
+ MojoChannel() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MojoChannel);
+};
+
+namespace {
+
+// The thin wrapper for InterfacePtr<T>, where T is one of ARC mojo Instance
+// class.
+template <typename T>
+class MojoChannelImpl : public ArcBridgeHostImpl::MojoChannel {
+ public:
+ MojoChannelImpl(InstanceHolder<T>* holder, mojo::InterfacePtr<T> ptr)
+ : holder_(holder), ptr_(std::move(ptr)) {
+ // Delay registration to the InstanceHolder until the version is ready.
+ }
+
+ ~MojoChannelImpl() override { holder_->SetInstance(nullptr, 0); }
+
+ void set_connection_error_handler(const base::Closure& error_handler) {
+ ptr_.set_connection_error_handler(error_handler);
+ }
+
+ void QueryVersion() {
+ // Note: the callback will not be called if |ptr_| is destroyed.
+ ptr_.QueryVersion(base::Bind(&MojoChannelImpl<T>::OnVersionReady,
+ base::Unretained(this)));
+ }
+
+ private:
+ void OnVersionReady(uint32_t unused_version) {
+ holder_->SetInstance(ptr_.get(), ptr_.version());
+ }
+
+ // Owned by ArcBridgeService.
+ InstanceHolder<T>* const holder_;
+
+ // Put as a last member to ensure that any callback tied to the |ptr_|
+ // is not invoked.
+ mojo::InterfacePtr<T> ptr_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoChannelImpl);
+};
+
+} // namespace
+
+ArcBridgeHostImpl::ArcBridgeHostImpl(mojom::ArcBridgeInstancePtr instance)
+ : binding_(this), instance_(std::move(instance)) {
+ DCHECK(instance_.is_bound());
+ instance_.set_connection_error_handler(
+ base::Bind(&ArcBridgeHostImpl::OnClosed, base::Unretained(this)));
+ instance_->Init(binding_.CreateInterfacePtrAndBind());
+}
+
+ArcBridgeHostImpl::~ArcBridgeHostImpl() {
+ OnClosed();
+}
+
+void ArcBridgeHostImpl::OnAppInstanceReady(mojom::AppInstancePtr app_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->app(), std::move(app_ptr));
+}
+
+void ArcBridgeHostImpl::OnAudioInstanceReady(
+ mojom::AudioInstancePtr audio_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->audio(), std::move(audio_ptr));
+}
+
+void ArcBridgeHostImpl::OnAuthInstanceReady(mojom::AuthInstancePtr auth_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->auth(), std::move(auth_ptr));
+}
+
+void ArcBridgeHostImpl::OnBluetoothInstanceReady(
+ mojom::BluetoothInstancePtr bluetooth_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->bluetooth(),
+ std::move(bluetooth_ptr));
+}
+
+void ArcBridgeHostImpl::OnBootPhaseMonitorInstanceReady(
+ mojom::BootPhaseMonitorInstancePtr boot_phase_monitor_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->boot_phase_monitor(),
+ std::move(boot_phase_monitor_ptr));
+}
+
+void ArcBridgeHostImpl::OnClipboardInstanceReady(
+ mojom::ClipboardInstancePtr clipboard_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->clipboard(),
+ std::move(clipboard_ptr));
+}
+
+void ArcBridgeHostImpl::OnCrashCollectorInstanceReady(
+ mojom::CrashCollectorInstancePtr crash_collector_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->crash_collector(),
+ std::move(crash_collector_ptr));
+}
+
+void ArcBridgeHostImpl::OnEnterpriseReportingInstanceReady(
+ mojom::EnterpriseReportingInstancePtr enterprise_reporting_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->enterprise_reporting(),
+ std::move(enterprise_reporting_ptr));
+}
+
+void ArcBridgeHostImpl::OnFileSystemInstanceReady(
+ mojom::FileSystemInstancePtr file_system_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->file_system(),
+ std::move(file_system_ptr));
+}
+
+void ArcBridgeHostImpl::OnImeInstanceReady(mojom::ImeInstancePtr ime_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->ime(), std::move(ime_ptr));
+}
+
+void ArcBridgeHostImpl::OnIntentHelperInstanceReady(
+ mojom::IntentHelperInstancePtr intent_helper_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->intent_helper(),
+ std::move(intent_helper_ptr));
+}
+
+void ArcBridgeHostImpl::OnMetricsInstanceReady(
+ mojom::MetricsInstancePtr metrics_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->metrics(), std::move(metrics_ptr));
+}
+
+void ArcBridgeHostImpl::OnNetInstanceReady(mojom::NetInstancePtr net_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->net(), std::move(net_ptr));
+}
+
+void ArcBridgeHostImpl::OnNotificationsInstanceReady(
+ mojom::NotificationsInstancePtr notifications_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->notifications(),
+ std::move(notifications_ptr));
+}
+
+void ArcBridgeHostImpl::OnObbMounterInstanceReady(
+ mojom::ObbMounterInstancePtr obb_mounter_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->obb_mounter(),
+ std::move(obb_mounter_ptr));
+}
+
+void ArcBridgeHostImpl::OnPolicyInstanceReady(
+ mojom::PolicyInstancePtr policy_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->policy(), std::move(policy_ptr));
+}
+
+void ArcBridgeHostImpl::OnPowerInstanceReady(
+ mojom::PowerInstancePtr power_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->power(), std::move(power_ptr));
+}
+
+void ArcBridgeHostImpl::OnPrintInstanceReady(
+ mojom::PrintInstancePtr print_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->print(), std::move(print_ptr));
+}
+
+void ArcBridgeHostImpl::OnProcessInstanceReady(
+ mojom::ProcessInstancePtr process_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->process(), std::move(process_ptr));
+}
+
+void ArcBridgeHostImpl::OnStorageManagerInstanceReady(
+ mojom::StorageManagerInstancePtr storage_manager_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->storage_manager(),
+ std::move(storage_manager_ptr));
+}
+
+void ArcBridgeHostImpl::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->tts(), std::move(tts_ptr));
+}
+
+void ArcBridgeHostImpl::OnVideoInstanceReady(
+ mojom::VideoInstancePtr video_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->video(), std::move(video_ptr));
+}
+
+void ArcBridgeHostImpl::OnWallpaperInstanceReady(
+ mojom::WallpaperInstancePtr wallpaper_ptr) {
+ OnInstanceReady(ArcBridgeService::Get()->wallpaper(),
+ std::move(wallpaper_ptr));
+}
+
+void ArcBridgeHostImpl::OnClosed() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ VLOG(1) << "Mojo connection lost";
+
+ // Close all mojo channels.
+ mojo_channels_.clear();
+ instance_.reset();
+ if (binding_.is_bound())
+ binding_.Close();
+}
+
+template <typename T>
+void ArcBridgeHostImpl::OnInstanceReady(InstanceHolder<T>* holder,
+ mojo::InterfacePtr<T> ptr) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(binding_.is_bound());
+ DCHECK(ptr.is_bound());
+
+ // Track |channel|'s lifetime via |mojo_channels_| so that it will be
+ // closed on ArcBridgeHost/Instance closing or the ArcBridgeHostImpl's
+ // destruction.
+ auto* channel = new MojoChannelImpl<T>(holder, std::move(ptr));
+ mojo_channels_.emplace_back(channel);
+
+ // Since |channel| is managed by |mojo_channels_|, its lifetime is shorter
+ // than |this|. Thus, the connection error handler will be invoked only
+ // when |this| is alive and base::Unretained is safe here.
+ channel->set_connection_error_handler(base::Bind(
+ &ArcBridgeHostImpl::OnChannelClosed, base::Unretained(this), channel));
+
+ // Call QueryVersion so that the version info is properly stored in the
+ // InterfacePtr<T>.
+ channel->QueryVersion();
+}
+
+void ArcBridgeHostImpl::OnChannelClosed(MojoChannel* channel) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ mojo_channels_.erase(
+ std::find_if(mojo_channels_.begin(), mojo_channels_.end(),
+ [channel](std::unique_ptr<MojoChannel>& ptr) {
+ return ptr.get() == channel;
+ }));
+}
+
+} // namespace arc