// 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/device/device_service.h" #include #include "base/bind.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/system/message_pipe.h" #include "services/device/binder_overrides.h" #include "services/device/bluetooth/bluetooth_system_factory.h" #include "services/device/fingerprint/fingerprint.h" #include "services/device/generic_sensor/platform_sensor_provider.h" #include "services/device/generic_sensor/sensor_provider_impl.h" #include "services/device/geolocation/geolocation_config.h" #include "services/device/geolocation/geolocation_context.h" #include "services/device/geolocation/public_ip_address_geolocator.h" #include "services/device/geolocation/public_ip_address_location_notifier.h" #include "services/device/power_monitor/power_monitor_message_broadcaster.h" #include "services/device/public/mojom/battery_monitor.mojom.h" #include "services/device/serial/serial_port_manager_impl.h" #include "services/device/time_zone_monitor/time_zone_monitor.h" #include "services/device/wake_lock/wake_lock_provider.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/gfx/native_widget_types.h" #if defined(OS_ANDROID) #include "base/android/jni_android.h" #include "services/device/device_service_jni_headers/InterfaceRegistrar_jni.h" #include "services/device/screen_orientation/screen_orientation_listener_android.h" #else #include "services/device/battery/battery_monitor_impl.h" #include "services/device/battery/battery_status_service.h" #include "services/device/hid/hid_manager_impl.h" #include "services/device/vibration/vibration_manager_impl.h" #endif #if defined(OS_LINUX) && defined(USE_UDEV) #include "services/device/hid/input_service_linux.h" #endif namespace device { #if defined(OS_ANDROID) std::unique_ptr CreateDeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, scoped_refptr url_loader_factory, network::NetworkConnectionTracker* network_connection_tracker, const std::string& geolocation_api_key, bool use_gms_core_location_provider, const WakeLockContextCallback& wake_lock_context_callback, const CustomLocationProviderCallback& custom_location_provider_callback, const base::android::JavaRef& java_nfc_delegate, mojo::PendingReceiver receiver) { GeolocationProviderImpl::SetGeolocationConfiguration( url_loader_factory, geolocation_api_key, custom_location_provider_callback, use_gms_core_location_provider); return std::make_unique( std::move(file_task_runner), std::move(io_task_runner), std::move(url_loader_factory), network_connection_tracker, geolocation_api_key, wake_lock_context_callback, java_nfc_delegate, std::move(receiver)); } #else std::unique_ptr CreateDeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, scoped_refptr url_loader_factory, network::NetworkConnectionTracker* network_connection_tracker, const std::string& geolocation_api_key, const CustomLocationProviderCallback& custom_location_provider_callback, mojo::PendingReceiver receiver) { GeolocationProviderImpl::SetGeolocationConfiguration( url_loader_factory, geolocation_api_key, custom_location_provider_callback); return std::make_unique( std::move(file_task_runner), std::move(io_task_runner), std::move(url_loader_factory), network_connection_tracker, geolocation_api_key, std::move(receiver)); } #endif #if defined(OS_ANDROID) DeviceService::DeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, scoped_refptr url_loader_factory, network::NetworkConnectionTracker* network_connection_tracker, const std::string& geolocation_api_key, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef& java_nfc_delegate, mojo::PendingReceiver receiver) : file_task_runner_(std::move(file_task_runner)), io_task_runner_(std::move(io_task_runner)), url_loader_factory_(std::move(url_loader_factory)), network_connection_tracker_(network_connection_tracker), geolocation_api_key_(geolocation_api_key), wake_lock_context_callback_(wake_lock_context_callback), wake_lock_provider_(file_task_runner_, wake_lock_context_callback_), java_interface_provider_initialized_(false) { receivers_.Add(this, std::move(receiver)); java_nfc_delegate_.Reset(java_nfc_delegate); } #else DeviceService::DeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, scoped_refptr url_loader_factory, network::NetworkConnectionTracker* network_connection_tracker, const std::string& geolocation_api_key, mojo::PendingReceiver receiver) : file_task_runner_(std::move(file_task_runner)), io_task_runner_(std::move(io_task_runner)), url_loader_factory_(std::move(url_loader_factory)), network_connection_tracker_(network_connection_tracker), geolocation_api_key_(geolocation_api_key), wake_lock_provider_(file_task_runner_, wake_lock_context_callback_) { receivers_.Add(this, std::move(receiver)); #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \ defined(OS_MACOSX) serial_port_manager_ = std::make_unique( io_task_runner_, base::ThreadTaskRunnerHandle::Get()); #if defined(OS_MACOSX) // On macOS the SerialDeviceEnumerator needs to run on the UI thread so that // it has access to a CFRunLoop where it can register a notification source. serial_port_manager_task_runner_ = base::ThreadTaskRunnerHandle::Get(); #else // On other platforms it must be allowed to do blocking IO. serial_port_manager_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); #endif #endif // Ensure that the battery backend is initialized now; otherwise it may end up // getting initialized on access during destruction, when it's no longer safe // to initialize. device::BatteryStatusService::GetInstance(); } #endif DeviceService::~DeviceService() { #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) // NOTE: We don't call this on Chrome OS due to https://crbug.com/856771, as // Shutdown() implicitly depends on DBusThreadManager, which may already be // destroyed by the time DeviceService is destroyed. Fortunately on Chrome OS // it's not really important that this runs anyway. device::BatteryStatusService::GetInstance()->Shutdown(); #endif #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \ defined(OS_MACOSX) serial_port_manager_task_runner_->DeleteSoon(FROM_HERE, std::move(serial_port_manager_)); #endif } void DeviceService::AddReceiver( mojo::PendingReceiver receiver) { receivers_.Add(this, std::move(receiver)); } void DeviceService::SetPlatformSensorProviderForTesting( std::unique_ptr provider) { DCHECK(!sensor_provider_); sensor_provider_ = std::make_unique(std::move(provider)); } // static void DeviceService::OverrideGeolocationContextBinderForTesting( GeolocationContextBinder binder) { internal::GetGeolocationContextBinderOverride() = std::move(binder); } void DeviceService::BindBatteryMonitor( mojo::PendingReceiver receiver) { #if defined(OS_ANDROID) GetJavaInterfaceProvider()->GetInterface(std::move(receiver)); #else BatteryMonitorImpl::Create(std::move(receiver)); #endif } void DeviceService::BindNFCProvider( mojo::PendingReceiver receiver) { #if defined(OS_ANDROID) GetJavaInterfaceProvider()->GetInterface(std::move(receiver)); #else LOG(ERROR) << "NFC is only supported on Android"; NOTREACHED(); #endif } void DeviceService::BindVibrationManager( mojo::PendingReceiver receiver) { #if defined(OS_ANDROID) GetJavaInterfaceProvider()->GetInterface(std::move(receiver)); #else VibrationManagerImpl::Create(std::move(receiver)); #endif } #if !defined(OS_ANDROID) void DeviceService::BindHidManager( mojo::PendingReceiver receiver) { if (!hid_manager_) hid_manager_ = std::make_unique(); hid_manager_->AddReceiver(std::move(receiver)); } #endif #if defined(OS_CHROMEOS) void DeviceService::BindBluetoothSystemFactory( mojo::PendingReceiver receiver) { BluetoothSystemFactory::CreateFactory(std::move(receiver)); } void DeviceService::BindMtpManager( mojo::PendingReceiver receiver) { if (!mtp_device_manager_) mtp_device_manager_ = MtpDeviceManager::Initialize(); mtp_device_manager_->AddReceiver(std::move(receiver)); } #endif #if defined(OS_LINUX) && defined(USE_UDEV) void DeviceService::BindInputDeviceManager( mojo::PendingReceiver receiver) { file_task_runner_->PostTask( FROM_HERE, base::BindOnce(&InputServiceLinux::BindReceiver, std::move(receiver))); } #endif void DeviceService::BindFingerprint( mojo::PendingReceiver receiver) { Fingerprint::Create(std::move(receiver)); } void DeviceService::BindGeolocationConfig( mojo::PendingReceiver receiver) { GeolocationConfig::Create(std::move(receiver)); } void DeviceService::BindGeolocationContext( mojo::PendingReceiver receiver) { const auto& binder_override = internal::GetGeolocationContextBinderOverride(); if (binder_override) { binder_override.Run(std::move(receiver)); return; } GeolocationContext::Create(std::move(receiver)); } void DeviceService::BindGeolocationControl( mojo::PendingReceiver receiver) { GeolocationProviderImpl::GetInstance()->BindGeolocationControlReceiver( std::move(receiver)); } void DeviceService::BindPowerMonitor( mojo::PendingReceiver receiver) { if (!power_monitor_message_broadcaster_) { power_monitor_message_broadcaster_ = std::make_unique(); } power_monitor_message_broadcaster_->Bind(std::move(receiver)); } void DeviceService::BindPublicIpAddressGeolocationProvider( mojo::PendingReceiver receiver) { if (!public_ip_address_geolocation_provider_) { public_ip_address_geolocation_provider_ = std::make_unique( url_loader_factory_, network_connection_tracker_, geolocation_api_key_); } public_ip_address_geolocation_provider_->Bind(std::move(receiver)); } void DeviceService::BindScreenOrientationListener( mojo::PendingReceiver receiver) { #if defined(OS_ANDROID) if (io_task_runner_) { io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&ScreenOrientationListenerAndroid::Create, std::move(receiver))); } #endif } void DeviceService::BindSensorProvider( mojo::PendingReceiver receiver) { if (!sensor_provider_) { auto platform_provider = PlatformSensorProvider::Create(); if (!platform_provider) return; sensor_provider_ = std::make_unique(std::move(platform_provider)); } sensor_provider_->Bind(std::move(receiver)); } void DeviceService::BindSerialPortManager( mojo::PendingReceiver receiver) { #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \ defined(OS_MACOSX) DCHECK(serial_port_manager_task_runner_); serial_port_manager_task_runner_->PostTask( FROM_HERE, base::BindOnce(&SerialPortManagerImpl::Bind, base::Unretained(serial_port_manager_.get()), std::move(receiver))); #else NOTREACHED() << "Serial devices not supported on this platform."; #endif } void DeviceService::BindTimeZoneMonitor( mojo::PendingReceiver receiver) { if (!time_zone_monitor_) time_zone_monitor_ = TimeZoneMonitor::Create(file_task_runner_); time_zone_monitor_->Bind(std::move(receiver)); } void DeviceService::BindWakeLockProvider( mojo::PendingReceiver receiver) { wake_lock_provider_.AddBinding(std::move(receiver)); } void DeviceService::BindUsbDeviceManager( mojo::PendingReceiver receiver) { if (!usb_device_manager_) usb_device_manager_ = std::make_unique(); usb_device_manager_->AddReceiver(std::move(receiver)); } void DeviceService::BindUsbDeviceManagerTest( mojo::PendingReceiver receiver) { if (!usb_device_manager_) usb_device_manager_ = std::make_unique(); if (!usb_device_manager_test_) { usb_device_manager_test_ = std::make_unique( usb_device_manager_->GetUsbService()); } usb_device_manager_test_->BindReceiver(std::move(receiver)); } #if defined(OS_ANDROID) service_manager::InterfaceProvider* DeviceService::GetJavaInterfaceProvider() { if (!java_interface_provider_initialized_) { mojo::PendingRemote provider; JNIEnv* env = base::android::AttachCurrentThread(); Java_InterfaceRegistrar_createInterfaceRegistryForContext( env, provider.InitWithNewPipeAndPassReceiver().PassPipe().release().value(), java_nfc_delegate_); java_interface_provider_.Bind(std::move(provider)); java_interface_provider_initialized_ = true; } return &java_interface_provider_; } #endif } // namespace device