// 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/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "device/geolocation/geolocation_config.h" #include "device/geolocation/geolocation_context.h" #include "mojo/public/cpp/system/message_pipe.h" #include "services/device/fingerprint/fingerprint.h" #include "services/device/generic_sensor/sensor_provider_impl.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_device_enumerator_impl.h" #include "services/device/serial/serial_io_handler_impl.h" #include "services/device/time_zone_monitor/time_zone_monitor.h" #include "services/device/wake_lock/wake_lock_provider.h" #include "ui/gfx/native_widget_types.h" #if defined(OS_ANDROID) #include "base/android/jni_android.h" #include "jni/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, const GeolocationProvider::RequestContextProducer geolocation_request_context_producer, const std::string& geolocation_api_key, const WakeLockContextCallback& wake_lock_context_callback, const CustomLocationProviderCallback& custom_location_provider_callback, const base::android::JavaRef& java_nfc_delegate) { GeolocationProviderImpl::SetGeolocationGlobals( geolocation_request_context_producer, geolocation_api_key, custom_location_provider_callback); return std::make_unique( std::move(file_task_runner), std::move(io_task_runner), std::move(geolocation_request_context_producer), geolocation_api_key, wake_lock_context_callback, java_nfc_delegate); } #else std::unique_ptr CreateDeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, const GeolocationProvider::RequestContextProducer geolocation_request_context_producer, const std::string& geolocation_api_key, const CustomLocationProviderCallback& custom_location_provider_callback) { GeolocationProviderImpl::SetGeolocationGlobals( geolocation_request_context_producer, geolocation_api_key, custom_location_provider_callback); return std::make_unique( std::move(file_task_runner), std::move(io_task_runner), std::move(geolocation_request_context_producer), geolocation_api_key); } #endif #if defined(OS_ANDROID) DeviceService::DeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, const GeolocationProvider::RequestContextProducer geolocation_request_context_producer, const std::string& geolocation_api_key, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef& java_nfc_delegate) : file_task_runner_(std::move(file_task_runner)), io_task_runner_(std::move(io_task_runner)), geolocation_request_context_producer_( geolocation_request_context_producer), geolocation_api_key_(geolocation_api_key), wake_lock_context_callback_(wake_lock_context_callback), java_interface_provider_initialized_(false) { java_nfc_delegate_.Reset(java_nfc_delegate); } #else DeviceService::DeviceService( scoped_refptr file_task_runner, scoped_refptr io_task_runner, const GeolocationProvider::RequestContextProducer geolocation_request_context_producer, const std::string& geolocation_api_key) : file_task_runner_(std::move(file_task_runner)), io_task_runner_(std::move(io_task_runner)), geolocation_request_context_producer_( geolocation_request_context_producer), geolocation_api_key_(geolocation_api_key) {} #endif DeviceService::~DeviceService() { #if !defined(OS_ANDROID) device::BatteryStatusService::GetInstance()->Shutdown(); #endif if (public_ip_address_geolocation_provider_) { DCHECK(io_task_runner_); io_task_runner_->DeleteSoon( FROM_HERE, std::move(public_ip_address_geolocation_provider_)); } } void DeviceService::OnStart() { registry_.AddInterface(base::Bind( &DeviceService::BindFingerprintRequest, base::Unretained(this))); registry_.AddInterface(base::BindRepeating( &DeviceService::BindGeolocationConfigRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindGeolocationContextRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindGeolocationControlRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindPowerMonitorRequest, base::Unretained(this))); registry_.AddInterface( base::Bind(&DeviceService::BindPublicIpAddressGeolocationProviderRequest, base::Unretained(this)), io_task_runner_); registry_.AddInterface( base::Bind(&DeviceService::BindScreenOrientationListenerRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindSensorProviderRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindTimeZoneMonitorRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindWakeLockProviderRequest, base::Unretained(this))); registry_.AddInterface( base::Bind(&DeviceService::BindSerialDeviceEnumeratorRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindSerialIoHandlerRequest, base::Unretained(this))); #if defined(OS_ANDROID) registry_.AddInterface(GetJavaInterfaceProvider() ->CreateInterfaceFactory()); registry_.AddInterface( GetJavaInterfaceProvider()->CreateInterfaceFactory()); registry_.AddInterface( GetJavaInterfaceProvider() ->CreateInterfaceFactory()); #else registry_.AddInterface(base::Bind( &DeviceService::BindBatteryMonitorRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindHidManagerRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindNFCProviderRequest, base::Unretained(this))); registry_.AddInterface(base::Bind( &DeviceService::BindVibrationManagerRequest, base::Unretained(this))); #endif #if defined(OS_LINUX) && defined(USE_UDEV) registry_.AddInterface(base::Bind( &DeviceService::BindInputDeviceManagerRequest, base::Unretained(this))); #endif } void DeviceService::OnBindInterface( const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { registry_.BindInterface(interface_name, std::move(interface_pipe)); } #if !defined(OS_ANDROID) void DeviceService::BindBatteryMonitorRequest( mojom::BatteryMonitorRequest request) { BatteryMonitorImpl::Create(std::move(request)); } void DeviceService::BindHidManagerRequest(mojom::HidManagerRequest request) { if (!hid_manager_) hid_manager_ = std::make_unique(); hid_manager_->AddBinding(std::move(request)); } void DeviceService::BindNFCProviderRequest(mojom::NFCProviderRequest request) { LOG(ERROR) << "NFC is only supported on Android"; NOTREACHED(); } void DeviceService::BindVibrationManagerRequest( mojom::VibrationManagerRequest request) { VibrationManagerImpl::Create(std::move(request)); } #endif #if defined(OS_LINUX) && defined(USE_UDEV) void DeviceService::BindInputDeviceManagerRequest( mojom::InputDeviceManagerRequest request) { file_task_runner_->PostTask( FROM_HERE, base::BindOnce(&InputServiceLinux::BindRequest, std::move(request))); } #endif void DeviceService::BindFingerprintRequest(mojom::FingerprintRequest request) { Fingerprint::Create(std::move(request)); } void DeviceService::BindGeolocationConfigRequest( mojom::GeolocationConfigRequest request) { GeolocationConfig::Create(std::move(request)); } void DeviceService::BindGeolocationContextRequest( mojom::GeolocationContextRequest request) { GeolocationContext::Create(std::move(request)); } void DeviceService::BindGeolocationControlRequest( mojom::GeolocationControlRequest request) { GeolocationProviderImpl::GetInstance()->BindGeolocationControlRequest( std::move(request)); } void DeviceService::BindPowerMonitorRequest( mojom::PowerMonitorRequest request) { if (!power_monitor_message_broadcaster_) { power_monitor_message_broadcaster_ = std::make_unique(); } power_monitor_message_broadcaster_->Bind(std::move(request)); } void DeviceService::BindPublicIpAddressGeolocationProviderRequest( mojom::PublicIpAddressGeolocationProviderRequest request) { // This needs to run on IO thread because it uses URLRequestContextGetters // which must not outlive that thread. DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); if (!public_ip_address_geolocation_provider_) { public_ip_address_geolocation_provider_ = std::make_unique( geolocation_request_context_producer_, geolocation_api_key_); } public_ip_address_geolocation_provider_->Bind(std::move(request)); } void DeviceService::BindScreenOrientationListenerRequest( mojom::ScreenOrientationListenerRequest request) { #if defined(OS_ANDROID) if (io_task_runner_) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&ScreenOrientationListenerAndroid::Create, base::Passed(&request))); } #endif } void DeviceService::BindSensorProviderRequest( mojom::SensorProviderRequest request) { if (io_task_runner_) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&device::SensorProviderImpl::Create, file_task_runner_, base::Passed(&request))); } } void DeviceService::BindTimeZoneMonitorRequest( mojom::TimeZoneMonitorRequest request) { if (!time_zone_monitor_) time_zone_monitor_ = TimeZoneMonitor::Create(file_task_runner_); time_zone_monitor_->Bind(std::move(request)); } void DeviceService::BindWakeLockProviderRequest( mojom::WakeLockProviderRequest request) { WakeLockProvider::Create(std::move(request), file_task_runner_, wake_lock_context_callback_); } void DeviceService::BindSerialDeviceEnumeratorRequest( mojom::SerialDeviceEnumeratorRequest request) { #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \ defined(OS_MACOSX) SerialDeviceEnumeratorImpl::Create(std::move(request)); #endif } void DeviceService::BindSerialIoHandlerRequest( mojom::SerialIoHandlerRequest request) { #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \ defined(OS_MACOSX) if (io_task_runner_) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&SerialIoHandlerImpl::Create, base::Passed(&request), base::ThreadTaskRunnerHandle::Get())); } #endif } #if defined(OS_ANDROID) service_manager::InterfaceProvider* DeviceService::GetJavaInterfaceProvider() { if (!java_interface_provider_initialized_) { service_manager::mojom::InterfaceProviderPtr provider; JNIEnv* env = base::android::AttachCurrentThread(); Java_InterfaceRegistrar_createInterfaceRegistryForContext( env, mojo::MakeRequest(&provider).PassMessagePipe().release().value(), java_nfc_delegate_); java_interface_provider_.Bind(std::move(provider)); java_interface_provider_initialized_ = true; } return &java_interface_provider_; } #endif } // namespace device