| // 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/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/kiosk.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::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::OnKioskInstanceReady( |
| mojo::PendingRemote<mojom::KioskInstance> kiosk_remote) { |
| OnInstanceReady(arc_bridge_service_->kiosk(), std::move(kiosk_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 { |
| 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 |