blob: 8710786a7f8554ea843d23e7f31e4dfc358846e0 [file] [log] [blame]
// 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 "ash/public/interfaces/ash_message_center_controller.mojom.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/mojo_channel.h"
#include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/connector.h"
namespace arc {
ArcBridgeHostImpl::ArcBridgeHostImpl(ArcBridgeService* arc_bridge_service,
mojom::ArcBridgeInstancePtr instance)
: arc_bridge_service_(arc_bridge_service),
binding_(this),
instance_(std::move(instance)) {
DCHECK(arc_bridge_service_);
DCHECK(instance_.is_bound());
instance_.set_connection_error_handler(
base::BindOnce(&ArcBridgeHostImpl::OnClosed, base::Unretained(this)));
mojom::ArcBridgeHostPtr host_proxy;
binding_.Bind(mojo::MakeRequest(&host_proxy));
instance_->Init(std::move(host_proxy));
}
ArcBridgeHostImpl::~ArcBridgeHostImpl() {
OnClosed();
}
void ArcBridgeHostImpl::OnAccessibilityHelperInstanceReady(
mojom::AccessibilityHelperInstancePtr accessibility_helper_ptr) {
OnInstanceReady(arc_bridge_service_->accessibility_helper(),
std::move(accessibility_helper_ptr));
}
void ArcBridgeHostImpl::OnAppInstanceReady(mojom::AppInstancePtr app_ptr) {
OnInstanceReady(arc_bridge_service_->app(), std::move(app_ptr));
}
void ArcBridgeHostImpl::OnAppfuseInstanceReady(
mojom::AppfuseInstancePtr appfuse_ptr) {
OnInstanceReady(arc_bridge_service_->appfuse(), std::move(appfuse_ptr));
}
void ArcBridgeHostImpl::OnAudioInstanceReady(
mojom::AudioInstancePtr audio_ptr) {
OnInstanceReady(arc_bridge_service_->audio(), std::move(audio_ptr));
}
void ArcBridgeHostImpl::OnAuthInstanceReady(mojom::AuthInstancePtr auth_ptr) {
OnInstanceReady(arc_bridge_service_->auth(), std::move(auth_ptr));
}
void ArcBridgeHostImpl::OnBackupSettingsInstanceReady(
mojom::BackupSettingsInstancePtr backup_settings_ptr) {
OnInstanceReady(arc_bridge_service_->backup_settings(),
std::move(backup_settings_ptr));
}
void ArcBridgeHostImpl::OnBluetoothInstanceReady(
mojom::BluetoothInstancePtr bluetooth_ptr) {
OnInstanceReady(arc_bridge_service_->bluetooth(), std::move(bluetooth_ptr));
}
void ArcBridgeHostImpl::OnBootPhaseMonitorInstanceReady(
mojom::BootPhaseMonitorInstancePtr boot_phase_monitor_ptr) {
OnInstanceReady(arc_bridge_service_->boot_phase_monitor(),
std::move(boot_phase_monitor_ptr));
}
void ArcBridgeHostImpl::OnCastReceiverInstanceReady(
mojom::CastReceiverInstancePtr cast_receiver_ptr) {
OnInstanceReady(arc_bridge_service_->cast_receiver(),
std::move(cast_receiver_ptr));
}
void ArcBridgeHostImpl::OnCertStoreInstanceReady(
mojom::CertStoreInstancePtr instance_ptr) {
OnInstanceReady(arc_bridge_service_->cert_store(), std::move(instance_ptr));
}
void ArcBridgeHostImpl::OnClipboardInstanceReady(
mojom::ClipboardInstancePtr clipboard_ptr) {
OnInstanceReady(arc_bridge_service_->clipboard(), std::move(clipboard_ptr));
}
void ArcBridgeHostImpl::OnCrashCollectorInstanceReady(
mojom::CrashCollectorInstancePtr crash_collector_ptr) {
OnInstanceReady(arc_bridge_service_->crash_collector(),
std::move(crash_collector_ptr));
}
void ArcBridgeHostImpl::OnDiskQuotaInstanceReady(
mojom::DiskQuotaInstancePtr disk_quota_ptr) {
OnInstanceReady(arc_bridge_service_->disk_quota(), std::move(disk_quota_ptr));
}
void ArcBridgeHostImpl::OnEnterpriseReportingInstanceReady(
mojom::EnterpriseReportingInstancePtr enterprise_reporting_ptr) {
OnInstanceReady(arc_bridge_service_->enterprise_reporting(),
std::move(enterprise_reporting_ptr));
}
void ArcBridgeHostImpl::OnFileSystemInstanceReady(
mojom::FileSystemInstancePtr file_system_ptr) {
OnInstanceReady(arc_bridge_service_->file_system(),
std::move(file_system_ptr));
}
void ArcBridgeHostImpl::OnImeInstanceReady(mojom::ImeInstancePtr ime_ptr) {
OnInstanceReady(arc_bridge_service_->ime(), std::move(ime_ptr));
}
void ArcBridgeHostImpl::OnInputMethodManagerInstanceReady(
mojom::InputMethodManagerInstancePtr input_method_manager_ptr) {
OnInstanceReady(arc_bridge_service_->input_method_manager(),
std::move(input_method_manager_ptr));
}
void ArcBridgeHostImpl::OnIntentHelperInstanceReady(
mojom::IntentHelperInstancePtr intent_helper_ptr) {
OnInstanceReady(arc_bridge_service_->intent_helper(),
std::move(intent_helper_ptr));
}
void ArcBridgeHostImpl::OnKioskInstanceReady(
mojom::KioskInstancePtr kiosk_ptr) {
OnInstanceReady(arc_bridge_service_->kiosk(), std::move(kiosk_ptr));
}
void ArcBridgeHostImpl::OnLockScreenInstanceReady(
mojom::LockScreenInstancePtr lock_screen_ptr) {
OnInstanceReady(arc_bridge_service_->lock_screen(),
std::move(lock_screen_ptr));
}
void ArcBridgeHostImpl::OnMetricsInstanceReady(
mojom::MetricsInstancePtr metrics_ptr) {
OnInstanceReady(arc_bridge_service_->metrics(), std::move(metrics_ptr));
}
void ArcBridgeHostImpl::OnMidisInstanceReady(
mojom::MidisInstancePtr midis_ptr) {
OnInstanceReady(arc_bridge_service_->midis(), std::move(midis_ptr));
}
void ArcBridgeHostImpl::OnNetInstanceReady(mojom::NetInstancePtr net_ptr) {
OnInstanceReady(arc_bridge_service_->net(), std::move(net_ptr));
}
void ArcBridgeHostImpl::OnNotificationsInstanceReady(
mojom::NotificationsInstancePtr notifications_ptr) {
// Forward notification instance to ash.
ash::mojom::AshMessageCenterControllerPtr ash_message_center_controller;
content::ServiceManagerConnection::GetForProcess()
->GetConnector()
->BindInterface(ash::mojom::kServiceName, &ash_message_center_controller);
ash_message_center_controller->SetArcNotificationsInstance(
std::move(notifications_ptr));
}
void ArcBridgeHostImpl::OnObbMounterInstanceReady(
mojom::ObbMounterInstancePtr obb_mounter_ptr) {
OnInstanceReady(arc_bridge_service_->obb_mounter(),
std::move(obb_mounter_ptr));
}
void ArcBridgeHostImpl::OnOemCryptoInstanceReady(
mojom::OemCryptoInstancePtr oemcrypto_ptr) {
OnInstanceReady(arc_bridge_service_->oemcrypto(), std::move(oemcrypto_ptr));
}
void ArcBridgeHostImpl::OnPipInstanceReady(mojom::PipInstancePtr pip_ptr) {
OnInstanceReady(arc_bridge_service_->pip(), std::move(pip_ptr));
}
void ArcBridgeHostImpl::OnPolicyInstanceReady(
mojom::PolicyInstancePtr policy_ptr) {
OnInstanceReady(arc_bridge_service_->policy(), std::move(policy_ptr));
}
void ArcBridgeHostImpl::OnPowerInstanceReady(
mojom::PowerInstancePtr power_ptr) {
OnInstanceReady(arc_bridge_service_->power(), std::move(power_ptr));
}
void ArcBridgeHostImpl::OnPrintInstanceReady(
mojom::PrintInstancePtr print_ptr) {
OnInstanceReady(arc_bridge_service_->print(), std::move(print_ptr));
}
void ArcBridgeHostImpl::OnProcessInstanceReady(
mojom::ProcessInstancePtr process_ptr) {
OnInstanceReady(arc_bridge_service_->process(), std::move(process_ptr));
}
void ArcBridgeHostImpl::OnRotationLockInstanceReady(
mojom::RotationLockInstancePtr rotation_lock_ptr) {
OnInstanceReady(arc_bridge_service_->rotation_lock(),
std::move(rotation_lock_ptr));
}
void ArcBridgeHostImpl::OnScreenCaptureInstanceReady(
mojom::ScreenCaptureInstancePtr screen_capture_ptr) {
OnInstanceReady(arc_bridge_service_->screen_capture(),
std::move(screen_capture_ptr));
}
void ArcBridgeHostImpl::OnStorageManagerInstanceReady(
mojom::StorageManagerInstancePtr storage_manager_ptr) {
OnInstanceReady(arc_bridge_service_->storage_manager(),
std::move(storage_manager_ptr));
}
void ArcBridgeHostImpl::OnTimerInstanceReady(
mojom::TimerInstancePtr timer_ptr) {
OnInstanceReady(arc_bridge_service_->timer(), std::move(timer_ptr));
}
void ArcBridgeHostImpl::OnTracingInstanceReady(
mojom::TracingInstancePtr tracing_ptr) {
OnInstanceReady(arc_bridge_service_->tracing(), std::move(tracing_ptr));
}
void ArcBridgeHostImpl::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) {
OnInstanceReady(arc_bridge_service_->tts(), std::move(tts_ptr));
}
void ArcBridgeHostImpl::OnUsbHostInstanceReady(
mojom::UsbHostInstancePtr usb_host_ptr) {
OnInstanceReady(arc_bridge_service_->usb_host(), std::move(usb_host_ptr));
}
void ArcBridgeHostImpl::OnVideoInstanceReady(
mojom::VideoInstancePtr video_ptr) {
OnInstanceReady(arc_bridge_service_->video(), std::move(video_ptr));
}
void ArcBridgeHostImpl::OnVoiceInteractionArcHomeInstanceReady(
mojom::VoiceInteractionArcHomeInstancePtr home_ptr) {
OnInstanceReady(arc_bridge_service_->voice_interaction_arc_home(),
std::move(home_ptr));
}
void ArcBridgeHostImpl::OnVoiceInteractionFrameworkInstanceReady(
mojom::VoiceInteractionFrameworkInstancePtr framework_ptr) {
OnInstanceReady(arc_bridge_service_->voice_interaction_framework(),
std::move(framework_ptr));
}
void ArcBridgeHostImpl::OnVolumeMounterInstanceReady(
mojom::VolumeMounterInstancePtr volume_mounter_ptr) {
OnInstanceReady(arc_bridge_service_->volume_mounter(),
std::move(volume_mounter_ptr));
}
void ArcBridgeHostImpl::OnWakeLockInstanceReady(
mojom::WakeLockInstancePtr wakelock_ptr) {
OnInstanceReady(arc_bridge_service_->wake_lock(), std::move(wakelock_ptr));
}
void ArcBridgeHostImpl::OnWallpaperInstanceReady(
mojom::WallpaperInstancePtr wallpaper_ptr) {
OnInstanceReady(arc_bridge_service_->wallpaper(), std::move(wallpaper_ptr));
}
void ArcBridgeHostImpl::OnClosed() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
VLOG(1) << "Mojo connection lost";
// Close all mojo channels.
mojo_channels_.clear();
instance_.reset();
if (binding_.is_bound())
binding_.Close();
}
template <typename InstanceType, typename HostType>
void ArcBridgeHostImpl::OnInstanceReady(
ConnectionHolder<InstanceType, HostType>* holder,
mojo::InterfacePtr<InstanceType> ptr) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
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 MojoChannel<InstanceType, HostType>(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::BindOnce(
&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(MojoChannelBase* channel) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
mojo_channels_.erase(
std::find_if(mojo_channels_.begin(), mojo_channels_.end(),
[channel](std::unique_ptr<MojoChannelBase>& ptr) {
return ptr.get() == channel;
}));
}
} // namespace arc