123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- // 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 <utility>
- #include "base/bind.h"
- #include "base/memory/weak_ptr.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/task/thread_pool.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.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/compute_pressure/pressure_manager_impl.h"
- #include "services/device/device_posture/device_posture_platform_provider.h"
- #include "services/device/device_posture/device_posture_provider_impl.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 BUILDFLAG(IS_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 (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV)
- #include "services/device/hid/input_service_linux.h"
- #endif
- #if BUILDFLAG(IS_CHROMEOS_LACROS)
- #include "chromeos/lacros/lacros_service.h"
- #endif
- namespace {
- #if !BUILDFLAG(IS_ANDROID)
- constexpr bool IsLaCrOS() {
- #if BUILDFLAG(IS_CHROMEOS_LACROS)
- return true;
- #else
- return false;
- #endif
- }
- #endif
- #if !BUILDFLAG(IS_ANDROID)
- void BindLaCrOSHidManager(
- mojo::PendingReceiver<device::mojom::HidManager> receiver) {
- #if BUILDFLAG(IS_CHROMEOS_LACROS)
- // LaCrOS does not have direct access to the permission_broker service over
- // D-Bus. Use the HidManager interface from ash-chrome instead.
- auto* lacros_service = chromeos::LacrosService::Get();
- DCHECK(lacros_service);
- // If the Hid manager is not available, then the pending receiver is deleted.
- if (lacros_service->IsAvailable<device::mojom::HidManager>()) {
- lacros_service->GetRemote<device::mojom::HidManager>()->AddReceiver(
- std::move(receiver));
- }
- #endif
- }
- #endif
- } // namespace
- namespace device {
- DeviceServiceParams::DeviceServiceParams() = default;
- DeviceServiceParams::~DeviceServiceParams() = default;
- std::unique_ptr<DeviceService> CreateDeviceService(
- std::unique_ptr<DeviceServiceParams> params,
- mojo::PendingReceiver<mojom::DeviceService> receiver) {
- GeolocationProviderImpl::SetGeolocationConfiguration(
- params->url_loader_factory, params->geolocation_api_key,
- params->custom_location_provider_callback, params->geolocation_manager,
- params->use_gms_core_location_provider);
- return std::make_unique<DeviceService>(std::move(params),
- std::move(receiver));
- }
- DeviceService::DeviceService(
- std::unique_ptr<DeviceServiceParams> params,
- mojo::PendingReceiver<mojom::DeviceService> receiver)
- : file_task_runner_(std::move(params->file_task_runner)),
- io_task_runner_(std::move(params->io_task_runner)),
- url_loader_factory_(std::move(params->url_loader_factory)),
- network_connection_tracker_(params->network_connection_tracker),
- geolocation_api_key_(params->geolocation_api_key),
- wake_lock_context_callback_(params->wake_lock_context_callback),
- wake_lock_provider_(file_task_runner_,
- params->wake_lock_context_callback) {
- receivers_.Add(this, std::move(receiver));
- #if BUILDFLAG(IS_ANDROID)
- java_nfc_delegate_.Reset(params->java_nfc_delegate);
- #endif
- #if defined(IS_SERIAL_ENABLED_PLATFORM)
- serial_port_manager_ = std::make_unique<SerialPortManagerImpl>(
- io_task_runner_, base::ThreadTaskRunnerHandle::Get());
- #if BUILDFLAG(IS_MAC)
- // 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 // defined(IS_SERIAL_ENABLED_PLATFORM)
- #if !BUILDFLAG(IS_ANDROID)
- // 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 // !BUILDFLAG(IS_ANDROID)
- }
- DeviceService::~DeviceService() {
- #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
- // 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(IS_SERIAL_ENABLED_PLATFORM)
- auto* serial_port_manager = serial_port_manager_.release();
- if (!serial_port_manager_task_runner_->DeleteSoon(FROM_HERE,
- serial_port_manager)) {
- // The ThreadPool can be shutdown by the time ~DeviceService is triggered.
- // Synchronously delete |serial_port_manager| in that event (which is
- // naturally sequenced after the last task on
- // |serial_port_manager_task_runner_| per ThreadPool shutdown semantics).
- // See crbug.com/1263149#c20 for details.
- delete serial_port_manager;
- }
- #endif // defined(IS_SERIAL_ENABLED_PLATFORM)
- }
- void DeviceService::AddReceiver(
- mojo::PendingReceiver<mojom::DeviceService> receiver) {
- receivers_.Add(this, std::move(receiver));
- }
- void DeviceService::SetPlatformSensorProviderForTesting(
- std::unique_ptr<PlatformSensorProvider> provider) {
- DCHECK(!sensor_provider_);
- sensor_provider_ = std::make_unique<SensorProviderImpl>(std::move(provider));
- }
- // static
- void DeviceService::OverrideGeolocationContextBinderForTesting(
- GeolocationContextBinder binder) {
- internal::GetGeolocationContextBinderOverride() = std::move(binder);
- }
- // static
- void DeviceService::OverridePressureManagerBinderForTesting(
- PressureManagerBinder binder) {
- internal::GetPressureManagerBinderOverride() = std::move(binder);
- }
- void DeviceService::BindBatteryMonitor(
- mojo::PendingReceiver<mojom::BatteryMonitor> receiver) {
- #if BUILDFLAG(IS_ANDROID)
- GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
- #else
- BatteryMonitorImpl::Create(std::move(receiver));
- #endif
- }
- void DeviceService::BindPressureManager(
- mojo::PendingReceiver<mojom::PressureManager> receiver) {
- const auto& binder_override = internal::GetPressureManagerBinderOverride();
- if (binder_override) {
- binder_override.Run(std::move(receiver));
- return;
- }
- if (!pressure_manager_)
- pressure_manager_ = PressureManagerImpl::Create();
- pressure_manager_->Bind(std::move(receiver));
- }
- #if BUILDFLAG(IS_ANDROID)
- // static
- void DeviceService::OverrideNFCProviderBinderForTesting(
- NFCProviderBinder binder) {
- internal::GetNFCProviderBinderOverride() = std::move(binder);
- }
- void DeviceService::BindNFCProvider(
- mojo::PendingReceiver<mojom::NFCProvider> receiver) {
- const auto& binder_override = internal::GetNFCProviderBinderOverride();
- if (binder_override)
- binder_override.Run(std::move(receiver));
- else
- GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
- }
- #endif
- void DeviceService::BindVibrationManager(
- mojo::PendingReceiver<mojom::VibrationManager> receiver) {
- #if BUILDFLAG(IS_ANDROID)
- GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
- #else
- VibrationManagerImpl::Create(std::move(receiver));
- #endif
- }
- #if !BUILDFLAG(IS_ANDROID)
- void DeviceService::BindHidManager(
- mojo::PendingReceiver<mojom::HidManager> receiver) {
- if (IsLaCrOS() && !HidManagerImpl::IsHidServiceTesting()) {
- BindLaCrOSHidManager(std::move(receiver));
- } else {
- if (!hid_manager_)
- hid_manager_ = std::make_unique<HidManagerImpl>();
- hid_manager_->AddReceiver(std::move(receiver));
- }
- }
- #endif
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- void DeviceService::BindBluetoothSystemFactory(
- mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver) {
- BluetoothSystemFactory::CreateFactory(std::move(receiver));
- }
- void DeviceService::BindMtpManager(
- mojo::PendingReceiver<mojom::MtpManager> receiver) {
- if (!mtp_device_manager_)
- mtp_device_manager_ = MtpDeviceManager::Initialize();
- mtp_device_manager_->AddReceiver(std::move(receiver));
- }
- #endif
- #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV)
- void DeviceService::BindInputDeviceManager(
- mojo::PendingReceiver<mojom::InputDeviceManager> receiver) {
- file_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&InputServiceLinux::BindReceiver, std::move(receiver)));
- }
- #endif
- void DeviceService::BindFingerprint(
- mojo::PendingReceiver<mojom::Fingerprint> receiver) {
- Fingerprint::Create(std::move(receiver));
- }
- void DeviceService::BindGeolocationConfig(
- mojo::PendingReceiver<mojom::GeolocationConfig> receiver) {
- GeolocationConfig::Create(std::move(receiver));
- }
- void DeviceService::BindGeolocationContext(
- mojo::PendingReceiver<mojom::GeolocationContext> 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<mojom::GeolocationControl> receiver) {
- GeolocationProviderImpl::GetInstance()->BindGeolocationControlReceiver(
- std::move(receiver));
- }
- void DeviceService::BindPowerMonitor(
- mojo::PendingReceiver<mojom::PowerMonitor> receiver) {
- if (!power_monitor_message_broadcaster_) {
- power_monitor_message_broadcaster_ =
- std::make_unique<PowerMonitorMessageBroadcaster>();
- }
- power_monitor_message_broadcaster_->Bind(std::move(receiver));
- }
- void DeviceService::BindPublicIpAddressGeolocationProvider(
- mojo::PendingReceiver<mojom::PublicIpAddressGeolocationProvider> receiver) {
- if (!public_ip_address_geolocation_provider_) {
- public_ip_address_geolocation_provider_ =
- std::make_unique<PublicIpAddressGeolocationProvider>(
- url_loader_factory_, network_connection_tracker_,
- geolocation_api_key_);
- }
- public_ip_address_geolocation_provider_->Bind(std::move(receiver));
- }
- void DeviceService::BindScreenOrientationListener(
- mojo::PendingReceiver<mojom::ScreenOrientationListener> receiver) {
- #if BUILDFLAG(IS_ANDROID)
- if (io_task_runner_) {
- io_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&ScreenOrientationListenerAndroid::Create,
- std::move(receiver)));
- }
- #endif
- }
- void DeviceService::BindSensorProvider(
- mojo::PendingReceiver<mojom::SensorProvider> receiver) {
- if (!sensor_provider_) {
- auto platform_provider = PlatformSensorProvider::Create();
- if (!platform_provider)
- return;
- sensor_provider_ =
- std::make_unique<SensorProviderImpl>(std::move(platform_provider));
- }
- sensor_provider_->Bind(std::move(receiver));
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
- void DeviceService::BindDevicePostureProvider(
- mojo::PendingReceiver<mojom::DevicePostureProvider> receiver) {
- if (!device_posture_provider_) {
- auto posture_platform_provider_ = DevicePosturePlatformProvider::Create();
- if (!posture_platform_provider_)
- return;
- device_posture_provider_ = std::make_unique<DevicePostureProviderImpl>(
- std::move(posture_platform_provider_));
- }
- device_posture_provider_->Bind(std::move(receiver));
- }
- #endif
- void DeviceService::BindSerialPortManager(
- mojo::PendingReceiver<mojom::SerialPortManager> receiver) {
- #if defined(IS_SERIAL_ENABLED_PLATFORM)
- // TODO(crbug.com/1109621): SerialPortManagerImpl depends on the
- // permission_broker service on Chromium OS. We will need to redirect
- // connections for LaCrOS here.
- 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 // defined(IS_SERIAL_ENABLED_PLATFORM)
- NOTREACHED() << "Serial devices not supported on this platform.";
- #endif // defined(IS_SERIAL_ENABLED_PLATFORM)
- }
- void DeviceService::BindTimeZoneMonitor(
- mojo::PendingReceiver<mojom::TimeZoneMonitor> 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<mojom::WakeLockProvider> receiver) {
- wake_lock_provider_.AddBinding(std::move(receiver));
- }
- void DeviceService::BindUsbDeviceManager(
- mojo::PendingReceiver<mojom::UsbDeviceManager> receiver) {
- // TODO(crbug.com/1109621): usb::DeviceManagerImpl depends on the
- // permission_broker service on Chromium OS. We will need to redirect
- // connections for LaCrOS here.
- if (!usb_device_manager_)
- usb_device_manager_ = std::make_unique<usb::DeviceManagerImpl>();
- usb_device_manager_->AddReceiver(std::move(receiver));
- }
- void DeviceService::BindUsbDeviceManagerTest(
- mojo::PendingReceiver<mojom::UsbDeviceManagerTest> receiver) {
- // TODO(crbug.com/1109621): usb::DeviceManagerImpl depends on the
- // permission_broker service on Chromium OS. We will need to redirect
- // connections for LaCrOS here.
- if (!usb_device_manager_)
- usb_device_manager_ = std::make_unique<usb::DeviceManagerImpl>();
- if (!usb_device_manager_test_) {
- usb_device_manager_test_ = std::make_unique<usb::DeviceManagerTest>(
- usb_device_manager_->GetUsbService());
- }
- usb_device_manager_test_->BindReceiver(std::move(receiver));
- }
- #if BUILDFLAG(IS_ANDROID)
- service_manager::InterfaceProvider* DeviceService::GetJavaInterfaceProvider() {
- if (!java_interface_provider_initialized_) {
- mojo::PendingRemote<service_manager::mojom::InterfaceProvider> 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
|