1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/device/device_service.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/task/post_task.h"
13 #include "base/task/thread_pool.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "build/build_config.h"
16 #include "mojo/public/cpp/bindings/pending_remote.h"
17 #include "mojo/public/cpp/system/message_pipe.h"
18 #include "services/device/binder_overrides.h"
19 #include "services/device/bluetooth/bluetooth_system_factory.h"
20 #include "services/device/fingerprint/fingerprint.h"
21 #include "services/device/generic_sensor/platform_sensor_provider.h"
22 #include "services/device/generic_sensor/sensor_provider_impl.h"
23 #include "services/device/geolocation/geolocation_config.h"
24 #include "services/device/geolocation/geolocation_context.h"
25 #include "services/device/geolocation/public_ip_address_geolocator.h"
26 #include "services/device/geolocation/public_ip_address_location_notifier.h"
27 #include "services/device/power_monitor/power_monitor_message_broadcaster.h"
28 #include "services/device/public/mojom/battery_monitor.mojom.h"
29 #include "services/device/serial/serial_port_manager_impl.h"
30 #include "services/device/time_zone_monitor/time_zone_monitor.h"
31 #include "services/device/wake_lock/wake_lock_provider.h"
32 #include "services/network/public/cpp/shared_url_loader_factory.h"
33 #include "ui/gfx/native_widget_types.h"
34
35 #if defined(OS_ANDROID)
36 #include "base/android/jni_android.h"
37 #include "services/device/device_service_jni_headers/InterfaceRegistrar_jni.h"
38 #include "services/device/screen_orientation/screen_orientation_listener_android.h"
39 #else
40 #include "services/device/battery/battery_monitor_impl.h"
41 #include "services/device/battery/battery_status_service.h"
42 #include "services/device/hid/hid_manager_impl.h"
43 #include "services/device/vibration/vibration_manager_impl.h"
44 #endif
45
46 #if defined(OS_LINUX) && defined(USE_UDEV)
47 #include "services/device/hid/input_service_linux.h"
48 #endif
49
50 namespace device {
51
52 #if defined(OS_ANDROID)
CreateDeviceService(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,scoped_refptr<network::SharedURLLoaderFactory> 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<jobject> & java_nfc_delegate,mojo::PendingReceiver<mojom::DeviceService> receiver)53 std::unique_ptr<DeviceService> CreateDeviceService(
54 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
55 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
56 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
57 network::NetworkConnectionTracker* network_connection_tracker,
58 const std::string& geolocation_api_key,
59 bool use_gms_core_location_provider,
60 const WakeLockContextCallback& wake_lock_context_callback,
61 const CustomLocationProviderCallback& custom_location_provider_callback,
62 const base::android::JavaRef<jobject>& java_nfc_delegate,
63 mojo::PendingReceiver<mojom::DeviceService> receiver) {
64 GeolocationProviderImpl::SetGeolocationConfiguration(
65 url_loader_factory, geolocation_api_key,
66 custom_location_provider_callback, use_gms_core_location_provider);
67 return std::make_unique<DeviceService>(
68 std::move(file_task_runner), std::move(io_task_runner),
69 std::move(url_loader_factory), network_connection_tracker,
70 geolocation_api_key, wake_lock_context_callback, java_nfc_delegate,
71 std::move(receiver));
72 }
73 #else
74 std::unique_ptr<DeviceService> CreateDeviceService(
75 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
76 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
77 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
78 network::NetworkConnectionTracker* network_connection_tracker,
79 const std::string& geolocation_api_key,
80 const CustomLocationProviderCallback& custom_location_provider_callback,
81 mojo::PendingReceiver<mojom::DeviceService> receiver) {
82 GeolocationProviderImpl::SetGeolocationConfiguration(
83 url_loader_factory, geolocation_api_key,
84 custom_location_provider_callback);
85 return std::make_unique<DeviceService>(
86 std::move(file_task_runner), std::move(io_task_runner),
87 std::move(url_loader_factory), network_connection_tracker,
88 geolocation_api_key, std::move(receiver));
89 }
90 #endif
91
92 #if defined(OS_ANDROID)
DeviceService(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,network::NetworkConnectionTracker * network_connection_tracker,const std::string & geolocation_api_key,const WakeLockContextCallback & wake_lock_context_callback,const base::android::JavaRef<jobject> & java_nfc_delegate,mojo::PendingReceiver<mojom::DeviceService> receiver)93 DeviceService::DeviceService(
94 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
95 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
96 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
97 network::NetworkConnectionTracker* network_connection_tracker,
98 const std::string& geolocation_api_key,
99 const WakeLockContextCallback& wake_lock_context_callback,
100 const base::android::JavaRef<jobject>& java_nfc_delegate,
101 mojo::PendingReceiver<mojom::DeviceService> receiver)
102 : file_task_runner_(std::move(file_task_runner)),
103 io_task_runner_(std::move(io_task_runner)),
104 url_loader_factory_(std::move(url_loader_factory)),
105 network_connection_tracker_(network_connection_tracker),
106 geolocation_api_key_(geolocation_api_key),
107 wake_lock_context_callback_(wake_lock_context_callback),
108 wake_lock_provider_(file_task_runner_, wake_lock_context_callback_),
109 java_interface_provider_initialized_(false) {
110 receivers_.Add(this, std::move(receiver));
111 java_nfc_delegate_.Reset(java_nfc_delegate);
112 }
113 #else
DeviceService(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,network::NetworkConnectionTracker * network_connection_tracker,const std::string & geolocation_api_key,mojo::PendingReceiver<mojom::DeviceService> receiver)114 DeviceService::DeviceService(
115 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
116 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
117 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
118 network::NetworkConnectionTracker* network_connection_tracker,
119 const std::string& geolocation_api_key,
120 mojo::PendingReceiver<mojom::DeviceService> receiver)
121 : file_task_runner_(std::move(file_task_runner)),
122 io_task_runner_(std::move(io_task_runner)),
123 url_loader_factory_(std::move(url_loader_factory)),
124 network_connection_tracker_(network_connection_tracker),
125 geolocation_api_key_(geolocation_api_key),
126 wake_lock_provider_(file_task_runner_, wake_lock_context_callback_) {
127 receivers_.Add(this, std::move(receiver));
128 #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \
129 defined(OS_MACOSX)
130 serial_port_manager_ = std::make_unique<SerialPortManagerImpl>(
131 io_task_runner_, base::ThreadTaskRunnerHandle::Get());
132 #if defined(OS_MACOSX)
133 // On macOS the SerialDeviceEnumerator needs to run on the UI thread so that
134 // it has access to a CFRunLoop where it can register a notification source.
135 serial_port_manager_task_runner_ = base::ThreadTaskRunnerHandle::Get();
136 #else
137 // On other platforms it must be allowed to do blocking IO.
138 serial_port_manager_task_runner_ =
139 base::ThreadPool::CreateSequencedTaskRunner(
140 {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
141 #endif
142 #endif
143 // Ensure that the battery backend is initialized now; otherwise it may end up
144 // getting initialized on access during destruction, when it's no longer safe
145 // to initialize.
146 device::BatteryStatusService::GetInstance();
147 }
148 #endif
149
~DeviceService()150 DeviceService::~DeviceService() {
151 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
152 // NOTE: We don't call this on Chrome OS due to https://crbug.com/856771, as
153 // Shutdown() implicitly depends on DBusThreadManager, which may already be
154 // destroyed by the time DeviceService is destroyed. Fortunately on Chrome OS
155 // it's not really important that this runs anyway.
156 device::BatteryStatusService::GetInstance()->Shutdown();
157 #endif
158 #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \
159 defined(OS_MACOSX)
160 serial_port_manager_task_runner_->DeleteSoon(FROM_HERE,
161 std::move(serial_port_manager_));
162 #endif
163 }
164
AddReceiver(mojo::PendingReceiver<mojom::DeviceService> receiver)165 void DeviceService::AddReceiver(
166 mojo::PendingReceiver<mojom::DeviceService> receiver) {
167 receivers_.Add(this, std::move(receiver));
168 }
169
SetPlatformSensorProviderForTesting(std::unique_ptr<PlatformSensorProvider> provider)170 void DeviceService::SetPlatformSensorProviderForTesting(
171 std::unique_ptr<PlatformSensorProvider> provider) {
172 DCHECK(!sensor_provider_);
173 sensor_provider_ = std::make_unique<SensorProviderImpl>(std::move(provider));
174 }
175
176 // static
OverrideGeolocationContextBinderForTesting(GeolocationContextBinder binder)177 void DeviceService::OverrideGeolocationContextBinderForTesting(
178 GeolocationContextBinder binder) {
179 internal::GetGeolocationContextBinderOverride() = std::move(binder);
180 }
181
BindBatteryMonitor(mojo::PendingReceiver<mojom::BatteryMonitor> receiver)182 void DeviceService::BindBatteryMonitor(
183 mojo::PendingReceiver<mojom::BatteryMonitor> receiver) {
184 #if defined(OS_ANDROID)
185 GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
186 #else
187 BatteryMonitorImpl::Create(std::move(receiver));
188 #endif
189 }
190
BindNFCProvider(mojo::PendingReceiver<mojom::NFCProvider> receiver)191 void DeviceService::BindNFCProvider(
192 mojo::PendingReceiver<mojom::NFCProvider> receiver) {
193 #if defined(OS_ANDROID)
194 GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
195 #else
196 LOG(ERROR) << "NFC is only supported on Android";
197 NOTREACHED();
198 #endif
199 }
200
BindVibrationManager(mojo::PendingReceiver<mojom::VibrationManager> receiver)201 void DeviceService::BindVibrationManager(
202 mojo::PendingReceiver<mojom::VibrationManager> receiver) {
203 #if defined(OS_ANDROID)
204 GetJavaInterfaceProvider()->GetInterface(std::move(receiver));
205 #else
206 VibrationManagerImpl::Create(std::move(receiver));
207 #endif
208 }
209
210 #if !defined(OS_ANDROID)
BindHidManager(mojo::PendingReceiver<mojom::HidManager> receiver)211 void DeviceService::BindHidManager(
212 mojo::PendingReceiver<mojom::HidManager> receiver) {
213 if (!hid_manager_)
214 hid_manager_ = std::make_unique<HidManagerImpl>();
215 hid_manager_->AddReceiver(std::move(receiver));
216 }
217 #endif
218
219 #if defined(OS_CHROMEOS)
BindBluetoothSystemFactory(mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver)220 void DeviceService::BindBluetoothSystemFactory(
221 mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver) {
222 BluetoothSystemFactory::CreateFactory(std::move(receiver));
223 }
224
BindMtpManager(mojo::PendingReceiver<mojom::MtpManager> receiver)225 void DeviceService::BindMtpManager(
226 mojo::PendingReceiver<mojom::MtpManager> receiver) {
227 if (!mtp_device_manager_)
228 mtp_device_manager_ = MtpDeviceManager::Initialize();
229 mtp_device_manager_->AddReceiver(std::move(receiver));
230 }
231 #endif
232
233 #if defined(OS_LINUX) && defined(USE_UDEV)
BindInputDeviceManager(mojo::PendingReceiver<mojom::InputDeviceManager> receiver)234 void DeviceService::BindInputDeviceManager(
235 mojo::PendingReceiver<mojom::InputDeviceManager> receiver) {
236 file_task_runner_->PostTask(
237 FROM_HERE,
238 base::BindOnce(&InputServiceLinux::BindReceiver, std::move(receiver)));
239 }
240 #endif
241
BindFingerprint(mojo::PendingReceiver<mojom::Fingerprint> receiver)242 void DeviceService::BindFingerprint(
243 mojo::PendingReceiver<mojom::Fingerprint> receiver) {
244 Fingerprint::Create(std::move(receiver));
245 }
246
BindGeolocationConfig(mojo::PendingReceiver<mojom::GeolocationConfig> receiver)247 void DeviceService::BindGeolocationConfig(
248 mojo::PendingReceiver<mojom::GeolocationConfig> receiver) {
249 GeolocationConfig::Create(std::move(receiver));
250 }
251
BindGeolocationContext(mojo::PendingReceiver<mojom::GeolocationContext> receiver)252 void DeviceService::BindGeolocationContext(
253 mojo::PendingReceiver<mojom::GeolocationContext> receiver) {
254 const auto& binder_override = internal::GetGeolocationContextBinderOverride();
255 if (binder_override) {
256 binder_override.Run(std::move(receiver));
257 return;
258 }
259
260 GeolocationContext::Create(std::move(receiver));
261 }
262
BindGeolocationControl(mojo::PendingReceiver<mojom::GeolocationControl> receiver)263 void DeviceService::BindGeolocationControl(
264 mojo::PendingReceiver<mojom::GeolocationControl> receiver) {
265 GeolocationProviderImpl::GetInstance()->BindGeolocationControlReceiver(
266 std::move(receiver));
267 }
268
BindPowerMonitor(mojo::PendingReceiver<mojom::PowerMonitor> receiver)269 void DeviceService::BindPowerMonitor(
270 mojo::PendingReceiver<mojom::PowerMonitor> receiver) {
271 if (!power_monitor_message_broadcaster_) {
272 power_monitor_message_broadcaster_ =
273 std::make_unique<PowerMonitorMessageBroadcaster>();
274 }
275 power_monitor_message_broadcaster_->Bind(std::move(receiver));
276 }
277
BindPublicIpAddressGeolocationProvider(mojo::PendingReceiver<mojom::PublicIpAddressGeolocationProvider> receiver)278 void DeviceService::BindPublicIpAddressGeolocationProvider(
279 mojo::PendingReceiver<mojom::PublicIpAddressGeolocationProvider> receiver) {
280 if (!public_ip_address_geolocation_provider_) {
281 public_ip_address_geolocation_provider_ =
282 std::make_unique<PublicIpAddressGeolocationProvider>(
283 url_loader_factory_, network_connection_tracker_,
284 geolocation_api_key_);
285 }
286 public_ip_address_geolocation_provider_->Bind(std::move(receiver));
287 }
288
BindScreenOrientationListener(mojo::PendingReceiver<mojom::ScreenOrientationListener> receiver)289 void DeviceService::BindScreenOrientationListener(
290 mojo::PendingReceiver<mojom::ScreenOrientationListener> receiver) {
291 #if defined(OS_ANDROID)
292 if (io_task_runner_) {
293 io_task_runner_->PostTask(
294 FROM_HERE, base::BindOnce(&ScreenOrientationListenerAndroid::Create,
295 std::move(receiver)));
296 }
297 #endif
298 }
299
BindSensorProvider(mojo::PendingReceiver<mojom::SensorProvider> receiver)300 void DeviceService::BindSensorProvider(
301 mojo::PendingReceiver<mojom::SensorProvider> receiver) {
302 if (!sensor_provider_) {
303 auto platform_provider = PlatformSensorProvider::Create();
304 if (!platform_provider)
305 return;
306 sensor_provider_ =
307 std::make_unique<SensorProviderImpl>(std::move(platform_provider));
308 }
309 sensor_provider_->Bind(std::move(receiver));
310 }
311
BindSerialPortManager(mojo::PendingReceiver<mojom::SerialPortManager> receiver)312 void DeviceService::BindSerialPortManager(
313 mojo::PendingReceiver<mojom::SerialPortManager> receiver) {
314 #if (defined(OS_LINUX) && defined(USE_UDEV)) || defined(OS_WIN) || \
315 defined(OS_MACOSX)
316 DCHECK(serial_port_manager_task_runner_);
317 serial_port_manager_task_runner_->PostTask(
318 FROM_HERE, base::BindOnce(&SerialPortManagerImpl::Bind,
319 base::Unretained(serial_port_manager_.get()),
320 std::move(receiver)));
321 #else
322 NOTREACHED() << "Serial devices not supported on this platform.";
323 #endif
324 }
325
BindTimeZoneMonitor(mojo::PendingReceiver<mojom::TimeZoneMonitor> receiver)326 void DeviceService::BindTimeZoneMonitor(
327 mojo::PendingReceiver<mojom::TimeZoneMonitor> receiver) {
328 if (!time_zone_monitor_)
329 time_zone_monitor_ = TimeZoneMonitor::Create(file_task_runner_);
330 time_zone_monitor_->Bind(std::move(receiver));
331 }
332
BindWakeLockProvider(mojo::PendingReceiver<mojom::WakeLockProvider> receiver)333 void DeviceService::BindWakeLockProvider(
334 mojo::PendingReceiver<mojom::WakeLockProvider> receiver) {
335 wake_lock_provider_.AddBinding(std::move(receiver));
336 }
337
BindUsbDeviceManager(mojo::PendingReceiver<mojom::UsbDeviceManager> receiver)338 void DeviceService::BindUsbDeviceManager(
339 mojo::PendingReceiver<mojom::UsbDeviceManager> receiver) {
340 if (!usb_device_manager_)
341 usb_device_manager_ = std::make_unique<usb::DeviceManagerImpl>();
342
343 usb_device_manager_->AddReceiver(std::move(receiver));
344 }
345
BindUsbDeviceManagerTest(mojo::PendingReceiver<mojom::UsbDeviceManagerTest> receiver)346 void DeviceService::BindUsbDeviceManagerTest(
347 mojo::PendingReceiver<mojom::UsbDeviceManagerTest> receiver) {
348 if (!usb_device_manager_)
349 usb_device_manager_ = std::make_unique<usb::DeviceManagerImpl>();
350
351 if (!usb_device_manager_test_) {
352 usb_device_manager_test_ = std::make_unique<usb::DeviceManagerTest>(
353 usb_device_manager_->GetUsbService());
354 }
355
356 usb_device_manager_test_->BindReceiver(std::move(receiver));
357 }
358
359 #if defined(OS_ANDROID)
GetJavaInterfaceProvider()360 service_manager::InterfaceProvider* DeviceService::GetJavaInterfaceProvider() {
361 if (!java_interface_provider_initialized_) {
362 mojo::PendingRemote<service_manager::mojom::InterfaceProvider> provider;
363 JNIEnv* env = base::android::AttachCurrentThread();
364 Java_InterfaceRegistrar_createInterfaceRegistryForContext(
365 env,
366 provider.InitWithNewPipeAndPassReceiver().PassPipe().release().value(),
367 java_nfc_delegate_);
368 java_interface_provider_.Bind(std::move(provider));
369
370 java_interface_provider_initialized_ = true;
371 }
372
373 return &java_interface_provider_;
374 }
375 #endif
376
377 } // namespace device
378