// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/components/arc/session/arc_bridge_host_impl.h"
#include <utility>
#include "ash/components/arc/mojom/adbd.mojom.h"
#include "ash/components/arc/mojom/app.mojom.h"
#include "ash/components/arc/mojom/app_permissions.mojom.h"
#include "ash/components/arc/mojom/appfuse.mojom.h"
#include "ash/components/arc/mojom/arc_wifi.mojom.h"
#include "ash/components/arc/mojom/audio.mojom.h"
#include "ash/components/arc/mojom/auth.mojom.h"
#include "ash/components/arc/mojom/backup_settings.mojom.h"
#include "ash/components/arc/mojom/bluetooth.mojom.h"
#include "ash/components/arc/mojom/boot_phase_monitor.mojom.h"
#include "ash/components/arc/mojom/camera.mojom.h"
#include "ash/components/arc/mojom/chrome_feature_flags.mojom.h"
#include "ash/components/arc/mojom/clipboard.mojom.h"
#include "ash/components/arc/mojom/compatibility_mode.mojom.h"
#include "ash/components/arc/mojom/crash_collector.mojom.h"
#include "ash/components/arc/mojom/digital_goods.mojom.h"
#include "ash/components/arc/mojom/disk_space.mojom.h"
#include "ash/components/arc/mojom/enterprise_reporting.mojom.h"
#include "ash/components/arc/mojom/error_notification.mojom.h"
#include "ash/components/arc/mojom/file_system.mojom.h"
#include "ash/components/arc/mojom/iio_sensor.mojom.h"
#include "ash/components/arc/mojom/ime.mojom.h"
#include "ash/components/arc/mojom/input_method_manager.mojom.h"
#include "ash/components/arc/mojom/intent_helper.mojom.h"
#include "ash/components/arc/mojom/keyboard_shortcut.mojom.h"
#include "ash/components/arc/mojom/keymaster.mojom.h"
#include "ash/components/arc/mojom/keymint.mojom.h"
#include "ash/components/arc/mojom/media_session.mojom.h"
#include "ash/components/arc/mojom/memory.mojom.h"
#include "ash/components/arc/mojom/metrics.mojom.h"
#include "ash/components/arc/mojom/midis.mojom.h"
#include "ash/components/arc/mojom/nearby_share.mojom.h"
#include "ash/components/arc/mojom/net.mojom.h"
#include "ash/components/arc/mojom/notifications.mojom.h"
#include "ash/components/arc/mojom/obb_mounter.mojom.h"
#include "ash/components/arc/mojom/oemcrypto.mojom.h"
#include "ash/components/arc/mojom/pip.mojom.h"
#include "ash/components/arc/mojom/policy.mojom.h"
#include "ash/components/arc/mojom/power.mojom.h"
#include "ash/components/arc/mojom/print_spooler.mojom.h"
#include "ash/components/arc/mojom/privacy_items.mojom.h"
#include "ash/components/arc/mojom/process.mojom.h"
#include "ash/components/arc/mojom/property.mojom.h"
#include "ash/components/arc/mojom/screen_capture.mojom.h"
#include "ash/components/arc/mojom/sharesheet.mojom.h"
#include "ash/components/arc/mojom/storage_manager.mojom.h"
#include "ash/components/arc/mojom/system_state.mojom.h"
#include "ash/components/arc/mojom/system_ui.mojom.h"
#include "ash/components/arc/mojom/timer.mojom.h"
#include "ash/components/arc/mojom/tracing.mojom.h"
#include "ash/components/arc/mojom/tts.mojom.h"
#include "ash/components/arc/mojom/usb_host.mojom.h"
#include "ash/components/arc/mojom/video.mojom.h"
#include "ash/components/arc/mojom/volume_mounter.mojom.h"
#include "ash/components/arc/mojom/wake_lock.mojom.h"
#include "ash/components/arc/mojom/wallpaper.mojom.h"
#include "ash/components/arc/mojom/webapk.mojom.h"
#include "ash/components/arc/session/arc_bridge_service.h"
#include "ash/components/arc/session/mojo_channel.h"
#include "ash/public/cpp/external_arc/message_center/arc_notification_manager.h"
#include "ash/public/cpp/message_center/arc_notifications_host_initializer.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/ranges/algorithm.h"
#include "chromeos/components/payments/mojom/payment_app.mojom.h"
#include "chromeos/components/sensors/mojom/cros_sensor_service.mojom.h"
#include "services/accessibility/android/public/mojom/accessibility_helper.mojom.h"
#include "third_party/cros_system_api/mojo/service_constants.h"
namespace arc {
ArcBridgeHostImpl::ArcBridgeHostImpl(ArcBridgeService* arc_bridge_service)
: arc_bridge_service_(arc_bridge_service) {
DCHECK(arc_bridge_service_);
receivers_.set_disconnect_handler(base::BindRepeating(
&ArcBridgeHostImpl::OnClosed, base::Unretained(this)));
// Register ArcBridgeHost to Mojo Service Manager.
if (!ash::mojo_service_manager::IsServiceManagerBound()) {
LOG(ERROR) << "mojo service manager not bounded";
return;
}
ash::mojo_service_manager::GetServiceManagerProxy()->Register(
chromeos::mojo_services::kChromiumArcBridgeHost,
provider_receiver_.BindNewPipeAndPassRemote());
}
ArcBridgeHostImpl::~ArcBridgeHostImpl() {
OnClosed();
}
void ArcBridgeHostImpl::AddReceiver(
mojo::PendingReceiver<mojom::ArcBridgeHost> pending_receiver) {
receivers_.Add(this, std::move(pending_receiver));
}
void ArcBridgeHostImpl::OnAccessibilityHelperInstanceReady(
mojo::PendingRemote<ax::android::mojom::AccessibilityHelperInstance>
accessibility_helper_remote) {
OnInstanceReady(arc_bridge_service_->accessibility_helper(),
std::move(accessibility_helper_remote));
}
void ArcBridgeHostImpl::OnAdbdMonitorInstanceReady(
mojo::PendingRemote<mojom::AdbdMonitorInstance> adbd_monitor_remote) {
OnInstanceReady(arc_bridge_service_->adbd_monitor(),
std::move(adbd_monitor_remote));
}
void ArcBridgeHostImpl::OnAppInstanceReady(
mojo::PendingRemote<mojom::AppInstance> app_remote) {
OnInstanceReady(arc_bridge_service_->app(), std::move(app_remote));
}
void ArcBridgeHostImpl::OnAppPermissionsInstanceReady(
mojo::PendingRemote<mojom::AppPermissionsInstance> app_permissions_remote) {
OnInstanceReady(arc_bridge_service_->app_permissions(),
std::move(app_permissions_remote));
}
void ArcBridgeHostImpl::OnAppfuseInstanceReady(
mojo::PendingRemote<mojom::AppfuseInstance> appfuse_remote) {
OnInstanceReady(arc_bridge_service_->appfuse(), std::move(appfuse_remote));
}
void ArcBridgeHostImpl::OnArcWifiInstanceReady(
mojo::PendingRemote<mojom::ArcWifiInstance> arc_wifi_remote) {
OnInstanceReady(arc_bridge_service_->arc_wifi(), std::move(arc_wifi_remote));
}
void ArcBridgeHostImpl::OnAudioInstanceReady(
mojo::PendingRemote<mojom::AudioInstance> audio_remote) {
OnInstanceReady(arc_bridge_service_->audio(), std::move(audio_remote));
}
void ArcBridgeHostImpl::OnAuthInstanceReady(
mojo::PendingRemote<mojom::AuthInstance> auth_remote) {
OnInstanceReady(arc_bridge_service_->auth(), std::move(auth_remote));
}
void ArcBridgeHostImpl::OnBackupSettingsInstanceReady(
mojo::PendingRemote<mojom::BackupSettingsInstance> backup_settings_remote) {
OnInstanceReady(arc_bridge_service_->backup_settings(),
std::move(backup_settings_remote));
}
void ArcBridgeHostImpl::OnBluetoothInstanceReady(
mojo::PendingRemote<mojom::BluetoothInstance> bluetooth_remote) {
OnInstanceReady(arc_bridge_service_->bluetooth(),
std::move(bluetooth_remote));
}
void ArcBridgeHostImpl::OnBootPhaseMonitorInstanceReady(
mojo::PendingRemote<mojom::BootPhaseMonitorInstance>
boot_phase_monitor_remote) {
OnInstanceReady(arc_bridge_service_->boot_phase_monitor(),
std::move(boot_phase_monitor_remote));
}
void ArcBridgeHostImpl::OnCameraInstanceReady(
mojo::PendingRemote<mojom::CameraInstance> camera_remote) {
OnInstanceReady(arc_bridge_service_->camera(), std::move(camera_remote));
}
void ArcBridgeHostImpl::OnChromeFeatureFlagsInstanceReady(
mojo::PendingRemote<mojom::ChromeFeatureFlagsInstance>
chrome_feature_flags_remote) {
OnInstanceReady(arc_bridge_service_->chrome_feature_flags(),
std::move(chrome_feature_flags_remote));
}
void ArcBridgeHostImpl::OnClipboardInstanceReady(
mojo::PendingRemote<mojom::ClipboardInstance> clipboard_remote) {
OnInstanceReady(arc_bridge_service_->clipboard(),
std::move(clipboard_remote));
}
void ArcBridgeHostImpl::OnCompatibilityModeInstanceReady(
mojo::PendingRemote<mojom::CompatibilityModeInstance>
compatibility_mode_remote) {
OnInstanceReady(arc_bridge_service_->compatibility_mode(),
std::move(compatibility_mode_remote));
}
void ArcBridgeHostImpl::OnCrashCollectorInstanceReady(
mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote) {
OnInstanceReady(arc_bridge_service_->crash_collector(),
std::move(crash_collector_remote));
}
void ArcBridgeHostImpl::OnDigitalGoodsInstanceReady(
mojo::PendingRemote<mojom::DigitalGoodsInstance> digital_goods_remote) {
OnInstanceReady(arc_bridge_service_->digital_goods(),
std::move(digital_goods_remote));
}
void ArcBridgeHostImpl::OnDiskSpaceInstanceReady(
mojo::PendingRemote<mojom::DiskSpaceInstance> disk_space_remote) {
OnInstanceReady(arc_bridge_service_->disk_space(),
std::move(disk_space_remote));
}
void ArcBridgeHostImpl::OnEnterpriseReportingInstanceReady(
mojo::PendingRemote<mojom::EnterpriseReportingInstance>
enterprise_reporting_remote) {
OnInstanceReady(arc_bridge_service_->enterprise_reporting(),
std::move(enterprise_reporting_remote));
}
void ArcBridgeHostImpl::OnErrorNotificationInstanceReady(
mojo::PendingRemote<mojom::ErrorNotificationInstance>
error_notification_remote) {
OnInstanceReady(arc_bridge_service_->error_notification(),
std::move(error_notification_remote));
}
void ArcBridgeHostImpl::OnFileSystemInstanceReady(
mojo::PendingRemote<mojom::FileSystemInstance> file_system_remote) {
OnInstanceReady(arc_bridge_service_->file_system(),
std::move(file_system_remote));
}
void ArcBridgeHostImpl::OnImeInstanceReady(
mojo::PendingRemote<mojom::ImeInstance> ime_remote) {
OnInstanceReady(arc_bridge_service_->ime(), std::move(ime_remote));
}
void ArcBridgeHostImpl::OnIioSensorInstanceReady(
mojo::PendingRemote<mojom::IioSensorInstance> iio_sensor_remote) {
OnInstanceReady(arc_bridge_service_->iio_sensor(),
std::move(iio_sensor_remote));
}
void ArcBridgeHostImpl::OnInputMethodManagerInstanceReady(
mojo::PendingRemote<mojom::InputMethodManagerInstance>
input_method_manager_remote) {
OnInstanceReady(arc_bridge_service_->input_method_manager(),
std::move(input_method_manager_remote));
}
void ArcBridgeHostImpl::OnIntentHelperInstanceReady(
mojo::PendingRemote<mojom::IntentHelperInstance> intent_helper_remote) {
OnInstanceReady(arc_bridge_service_->intent_helper(),
std::move(intent_helper_remote));
}
void ArcBridgeHostImpl::OnKeyboardShortcutInstanceReady(
mojo::PendingRemote<mojom::KeyboardShortcutInstance>
keyboard_shortcut_remote) {
OnInstanceReady(arc_bridge_service_->keyboard_shortcut(),
std::move(keyboard_shortcut_remote));
}
void ArcBridgeHostImpl::OnKeymasterInstanceReady(
mojo::PendingRemote<mojom::KeymasterInstance> keymaster_remote) {
OnInstanceReady(arc_bridge_service_->keymaster(),
std::move(keymaster_remote));
}
void ArcBridgeHostImpl::OnKeyMintInstanceReady(
mojo::PendingRemote<mojom::keymint::KeyMintInstance> keymint_remote) {
OnInstanceReady(arc_bridge_service_->keymint(), std::move(keymint_remote));
}
void ArcBridgeHostImpl::OnMediaSessionInstanceReady(
mojo::PendingRemote<mojom::MediaSessionInstance> media_session_remote) {
OnInstanceReady(arc_bridge_service_->media_session(),
std::move(media_session_remote));
}
void ArcBridgeHostImpl::OnMemoryInstanceReady(
mojo::PendingRemote<mojom::MemoryInstance> memory_remote) {
OnInstanceReady(arc_bridge_service_->memory(), std::move(memory_remote));
}
void ArcBridgeHostImpl::OnMetricsInstanceReady(
mojo::PendingRemote<mojom::MetricsInstance> metrics_remote) {
OnInstanceReady(arc_bridge_service_->metrics(), std::move(metrics_remote));
}
void ArcBridgeHostImpl::OnMidisInstanceReady(
mojo::PendingRemote<mojom::MidisInstance> midis_remote) {
OnInstanceReady(arc_bridge_service_->midis(), std::move(midis_remote));
}
void ArcBridgeHostImpl::OnNearbyShareInstanceReady(
mojo::PendingRemote<mojom::NearbyShareInstance> nearby_share_remote) {
OnInstanceReady(arc_bridge_service_->nearby_share(),
std::move(nearby_share_remote));
}
void ArcBridgeHostImpl::OnNetInstanceReady(
mojo::PendingRemote<mojom::NetInstance> net_remote) {
OnInstanceReady(arc_bridge_service_->net(), std::move(net_remote));
}
void ArcBridgeHostImpl::OnNotificationsInstanceReady(
mojo::PendingRemote<mojom::NotificationsInstance> notifications_remote) {
auto* host_initializer = ash::ArcNotificationsHostInitializer::Get();
auto* manager = host_initializer->GetArcNotificationManagerInstance();
if (manager) {
static_cast<ash::ArcNotificationManager*>(manager)->SetInstance(
std::move(notifications_remote));
return;
}
// Forward notification instance to ash by injecting ArcNotificationManager.
auto new_manager = std::make_unique<ash::ArcNotificationManager>();
new_manager->SetInstance(std::move(notifications_remote));
ash::ArcNotificationsHostInitializer::Get()
->SetArcNotificationManagerInstance(std::move(new_manager));
}
void ArcBridgeHostImpl::OnObbMounterInstanceReady(
mojo::PendingRemote<mojom::ObbMounterInstance> obb_mounter_remote) {
OnInstanceReady(arc_bridge_service_->obb_mounter(),
std::move(obb_mounter_remote));
}
void ArcBridgeHostImpl::OnOemCryptoInstanceReady(
mojo::PendingRemote<mojom::OemCryptoInstance> oemcrypto_remote) {
OnInstanceReady(arc_bridge_service_->oemcrypto(),
std::move(oemcrypto_remote));
}
void ArcBridgeHostImpl::OnPaymentAppInstanceReady(
mojo::PendingRemote<chromeos::payments::mojom::PaymentAppInstance>
payment_app_remote) {
OnInstanceReady(arc_bridge_service_->payment_app(),
std::move(payment_app_remote));
}
void ArcBridgeHostImpl::OnPipInstanceReady(
mojo::PendingRemote<mojom::PipInstance> pip_remote) {
OnInstanceReady(arc_bridge_service_->pip(), std::move(pip_remote));
}
void ArcBridgeHostImpl::OnPolicyInstanceReady(
mojo::PendingRemote<mojom::PolicyInstance> policy_remote) {
OnInstanceReady(arc_bridge_service_->policy(), std::move(policy_remote));
}
void ArcBridgeHostImpl::OnPowerInstanceReady(
mojo::PendingRemote<mojom::PowerInstance> power_remote) {
OnInstanceReady(arc_bridge_service_->power(), std::move(power_remote));
}
void ArcBridgeHostImpl::OnPrintSpoolerInstanceReady(
mojo::PendingRemote<mojom::PrintSpoolerInstance> print_spooler_remote) {
OnInstanceReady(arc_bridge_service_->print_spooler(),
std::move(print_spooler_remote));
}
void ArcBridgeHostImpl::OnPrivacyItemsInstanceReady(
mojo::PendingRemote<mojom::PrivacyItemsInstance> privacy_items_remote) {
OnInstanceReady(arc_bridge_service_->privacy_items(),
std::move(privacy_items_remote));
}
void ArcBridgeHostImpl::OnProcessInstanceReady(
mojo::PendingRemote<mojom::ProcessInstance> process_remote) {
OnInstanceReady(arc_bridge_service_->process(), std::move(process_remote));
}
void ArcBridgeHostImpl::OnPropertyInstanceReady(
mojo::PendingRemote<mojom::PropertyInstance> property_remote) {
OnInstanceReady(arc_bridge_service_->property(), std::move(property_remote));
}
void ArcBridgeHostImpl::OnScreenCaptureInstanceReady(
mojo::PendingRemote<mojom::ScreenCaptureInstance> screen_capture_remote) {
OnInstanceReady(arc_bridge_service_->screen_capture(),
std::move(screen_capture_remote));
}
void ArcBridgeHostImpl::OnSharesheetInstanceReady(
mojo::PendingRemote<mojom::SharesheetInstance> sharesheet_remote) {
OnInstanceReady(arc_bridge_service_->sharesheet(),
std::move(sharesheet_remote));
}
void ArcBridgeHostImpl::OnStorageManagerInstanceReady(
mojo::PendingRemote<mojom::StorageManagerInstance> storage_manager_remote) {
OnInstanceReady(arc_bridge_service_->storage_manager(),
std::move(storage_manager_remote));
}
void ArcBridgeHostImpl::OnSystemStateInstanceReady(
mojo::PendingRemote<mojom::SystemStateInstance> system_state_remote) {
OnInstanceReady(arc_bridge_service_->system_state(),
std::move(system_state_remote));
}
void ArcBridgeHostImpl::OnSystemUiInstanceReady(
mojo::PendingRemote<mojom::SystemUiInstance> system_ui_remote) {
OnInstanceReady(arc_bridge_service_->system_ui(),
std::move(system_ui_remote));
}
void ArcBridgeHostImpl::OnTimerInstanceReady(
mojo::PendingRemote<mojom::TimerInstance> timer_remote) {
OnInstanceReady(arc_bridge_service_->timer(), std::move(timer_remote));
}
void ArcBridgeHostImpl::OnTracingInstanceReady(
mojo::PendingRemote<mojom::TracingInstance> tracing_remote) {
OnInstanceReady(arc_bridge_service_->tracing(), std::move(tracing_remote));
}
void ArcBridgeHostImpl::OnTtsInstanceReady(
mojo::PendingRemote<mojom::TtsInstance> tts_remote) {
OnInstanceReady(arc_bridge_service_->tts(), std::move(tts_remote));
}
void ArcBridgeHostImpl::OnUsbHostInstanceReady(
mojo::PendingRemote<mojom::UsbHostInstance> usb_host_remote) {
OnInstanceReady(arc_bridge_service_->usb_host(), std::move(usb_host_remote));
}
void ArcBridgeHostImpl::OnVideoInstanceReady(
mojo::PendingRemote<mojom::VideoInstance> video_remote) {
OnInstanceReady(arc_bridge_service_->video(), std::move(video_remote));
}
void ArcBridgeHostImpl::OnVolumeMounterInstanceReady(
mojo::PendingRemote<mojom::VolumeMounterInstance> volume_mounter_remote) {
OnInstanceReady(arc_bridge_service_->volume_mounter(),
std::move(volume_mounter_remote));
}
void ArcBridgeHostImpl::OnWakeLockInstanceReady(
mojo::PendingRemote<mojom::WakeLockInstance> wakelock_remote) {
OnInstanceReady(arc_bridge_service_->wake_lock(), std::move(wakelock_remote));
}
void ArcBridgeHostImpl::OnWallpaperInstanceReady(
mojo::PendingRemote<mojom::WallpaperInstance> wallpaper_remote) {
OnInstanceReady(arc_bridge_service_->wallpaper(),
std::move(wallpaper_remote));
}
void ArcBridgeHostImpl::OnWebApkInstanceReady(
mojo::PendingRemote<mojom::WebApkInstance> webapk_remote) {
OnInstanceReady(arc_bridge_service_->webapk(), std::move(webapk_remote));
}
size_t ArcBridgeHostImpl::GetNumMojoChannelsForTesting() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return mojo_channels_.size();
}
void ArcBridgeHostImpl::Request(
chromeos::mojo_service_manager::mojom::ProcessIdentityPtr identity,
mojo::ScopedMessagePipeHandle receiver) {
receivers_.Add(
this, mojo::PendingReceiver<mojom::ArcBridgeHost>(std::move(receiver)));
}
void ArcBridgeHostImpl::OnClosed() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
VLOG(1) << "Mojo connection lost";
arc_bridge_service_->ObserveBeforeArcBridgeClosed();
// Close all mojo channels.
mojo_channels_.clear();
receivers_.Clear();
arc_bridge_service_->ObserveAfterArcBridgeClosed();
}
template <typename InstanceType, typename HostType>
void ArcBridgeHostImpl::OnInstanceReady(
ConnectionHolder<InstanceType, HostType>* holder,
mojo::PendingRemote<InstanceType> remote) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(receivers_.size());
DCHECK(remote.is_valid());
// 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(remote));
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_disconnect_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(base::ranges::find(
mojo_channels_, channel, &std::unique_ptr<MojoChannelBase>::get));
}
} // namespace arc