Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 5 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "content/browser/bad_message.h" | 8 #include "content/browser/bad_message.h" |
| 9 #include "content/common/bluetooth/bluetooth_messages.h" | 9 #include "content/common/bluetooth/bluetooth_messages.h" |
| 10 #include "device/bluetooth/bluetooth_adapter.h" | 10 #include "device/bluetooth/bluetooth_adapter.h" |
| 11 #include "device/bluetooth/bluetooth_adapter_factory.h" | 11 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 12 #include "device/bluetooth/bluetooth_device.h" | 12 #include "device/bluetooth/bluetooth_device.h" |
| 13 #include "device/bluetooth/bluetooth_discovery_session.h" | 13 #include "device/bluetooth/bluetooth_discovery_session.h" |
| 14 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 14 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 15 #include "device/bluetooth/bluetooth_gatt_service.h" | 15 #include "device/bluetooth/bluetooth_gatt_service.h" |
| 16 | 16 |
| 17 using device::BluetoothAdapter; | 17 using device::BluetoothAdapter; |
| 18 using device::BluetoothAdapterFactory; | 18 using device::BluetoothAdapterFactory; |
| 19 using device::BluetoothGattCharacteristic; | 19 using device::BluetoothGattCharacteristic; |
| 20 using device::BluetoothGattService; | 20 using device::BluetoothGattService; |
| 21 using device::BluetoothUUID; | |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 24 |
| 24 // TODO(ortuno): Once we have a chooser for scanning and the right | 25 // TODO(ortuno): Once we have a chooser for scanning and the right |
| 25 // callback for discovered services we should delete these constants. | 26 // callback for discovered services we should delete these constants. |
| 26 // https://crbug.com/436280 and https://crbug.com/484504 | 27 // https://crbug.com/436280 and https://crbug.com/484504 |
| 27 const int kDelayTime = 5; // 5 seconds for scanning and discovering | 28 const int kDelayTime = 5; // 5 seconds for scanning and discovering |
| 28 const int kTestingDelayTime = 0; // No need to wait during tests | 29 const int kTestingDelayTime = 0; // No need to wait during tests |
| 29 | 30 |
| 30 BluetoothDispatcherHost::BluetoothDispatcherHost() | 31 BluetoothDispatcherHost::BluetoothDispatcherHost() |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 current_delay_time_ = kTestingDelayTime; | 71 current_delay_time_ = kTestingDelayTime; |
| 71 set_adapter(mock_adapter.Pass()); | 72 set_adapter(mock_adapter.Pass()); |
| 72 } | 73 } |
| 73 | 74 |
| 74 BluetoothDispatcherHost::~BluetoothDispatcherHost() { | 75 BluetoothDispatcherHost::~BluetoothDispatcherHost() { |
| 75 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 76 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 76 // Clear adapter, releasing observer references. | 77 // Clear adapter, releasing observer references. |
| 77 set_adapter(scoped_refptr<device::BluetoothAdapter>()); | 78 set_adapter(scoped_refptr<device::BluetoothAdapter>()); |
| 78 } | 79 } |
| 79 | 80 |
| 81 struct BluetoothDispatcherHost::DiscoverySessionOptions { | |
| 82 DiscoverySessionOptions(const std::vector<BluetoothScanFilter>& filters, | |
| 83 const std::vector<BluetoothUUID>& optional_services) | |
| 84 : filters(filters), optional_services(optional_services) {} | |
| 85 | |
| 86 std::vector<BluetoothScanFilter> filters; | |
| 87 std::vector<BluetoothUUID> optional_services; | |
| 88 }; | |
| 89 | |
| 80 void BluetoothDispatcherHost::set_adapter( | 90 void BluetoothDispatcherHost::set_adapter( |
| 81 scoped_refptr<device::BluetoothAdapter> adapter) { | 91 scoped_refptr<device::BluetoothAdapter> adapter) { |
| 82 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 92 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 83 if (adapter_.get()) | 93 if (adapter_.get()) |
| 84 adapter_->RemoveObserver(this); | 94 adapter_->RemoveObserver(this); |
| 85 adapter_ = adapter; | 95 adapter_ = adapter; |
| 86 if (adapter_.get()) | 96 if (adapter_.get()) |
| 87 adapter_->AddObserver(this); | 97 adapter_->AddObserver(this); |
| 88 } | 98 } |
| 89 | 99 |
| 90 void BluetoothDispatcherHost::OnRequestDevice(int thread_id, int request_id) { | 100 static scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( |
|
ortuno
2015/06/15 22:49:27
Shouldn't this be in an anonymous namespace?
Jeffrey Yasskin
2015/06/15 23:48:22
It's static, which has the same effect. Making it
Jeffrey Yasskin
2015/06/16 00:48:10
Done per Vince's comment elsewhere.
| |
| 101 const std::vector<BluetoothScanFilter>& filters) { | |
| 102 std::set<BluetoothUUID> services; | |
| 103 for (const BluetoothScanFilter& filter : filters) { | |
| 104 services.insert(filter.services.begin(), filter.services.end()); | |
| 105 } | |
| 106 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( | |
| 107 new device::BluetoothDiscoveryFilter( | |
| 108 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); | |
| 109 for (const BluetoothUUID& service : services) { | |
| 110 discovery_filter->AddUUID(service); | |
| 111 } | |
| 112 return discovery_filter.Pass(); | |
| 113 } | |
| 114 | |
| 115 void BluetoothDispatcherHost::OnRequestDevice( | |
| 116 int thread_id, | |
| 117 int request_id, | |
| 118 const std::vector<BluetoothScanFilter>& filters, | |
| 119 const std::vector<BluetoothUUID>& optional_services) { | |
| 91 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 120 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 92 // TODO(scheib): Filter devices by services: crbug.com/440594 | |
| 93 // TODO(scheib): Device selection UI: crbug.com/436280 | 121 // TODO(scheib): Device selection UI: crbug.com/436280 |
| 94 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed. | 122 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed. |
| 95 if (adapter_.get()) { | 123 if (adapter_.get()) { |
| 96 adapter_->StartDiscoverySession( | 124 adapter_->StartDiscoverySessionWithFilter( |
| 125 ComputeScanFilter(filters), | |
| 97 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted, | 126 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted, |
| 98 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 127 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
| 128 base::Passed(make_scoped_ptr(new DiscoverySessionOptions( | |
| 129 filters, optional_services)))), | |
| 99 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError, | 130 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError, |
| 100 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 131 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
| 101 } else { | 132 } else { |
| 102 DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice."; | 133 DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice."; |
| 103 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, | 134 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, |
| 104 BluetoothError::NOT_FOUND)); | 135 BluetoothError::NOT_FOUND)); |
| 105 } | 136 } |
| 106 return; | 137 return; |
| 107 } | 138 } |
| 108 | 139 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 characteristic->ReadRemoteCharacteristic( | 303 characteristic->ReadRemoteCharacteristic( |
| 273 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 304 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
| 274 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 305 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
| 275 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 306 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
| 276 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 307 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
| 277 } | 308 } |
| 278 | 309 |
| 279 void BluetoothDispatcherHost::OnDiscoverySessionStarted( | 310 void BluetoothDispatcherHost::OnDiscoverySessionStarted( |
| 280 int thread_id, | 311 int thread_id, |
| 281 int request_id, | 312 int request_id, |
| 313 scoped_ptr<DiscoverySessionOptions> options, | |
| 282 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | 314 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { |
| 283 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 315 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 284 BrowserThread::PostDelayedTask( | 316 BrowserThread::PostDelayedTask( |
| 285 BrowserThread::UI, FROM_HERE, | 317 BrowserThread::UI, FROM_HERE, |
| 286 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession, | 318 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession, |
| 287 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 319 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
| 288 base::Passed(&discovery_session)), | 320 base::Passed(&options), base::Passed(&discovery_session)), |
| 289 base::TimeDelta::FromSeconds(current_delay_time_)); | 321 base::TimeDelta::FromSeconds(current_delay_time_)); |
| 290 } | 322 } |
| 291 | 323 |
| 292 void BluetoothDispatcherHost::OnDiscoverySessionStartedError(int thread_id, | 324 void BluetoothDispatcherHost::OnDiscoverySessionStartedError(int thread_id, |
| 293 int request_id) { | 325 int request_id) { |
| 294 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 326 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 295 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStartedError"; | 327 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStartedError"; |
| 296 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, | 328 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, |
| 297 BluetoothError::NOT_FOUND)); | 329 BluetoothError::NOT_FOUND)); |
| 298 } | 330 } |
| 299 | 331 |
| 300 void BluetoothDispatcherHost::StopDiscoverySession( | 332 void BluetoothDispatcherHost::StopDiscoverySession( |
| 301 int thread_id, | 333 int thread_id, |
| 302 int request_id, | 334 int request_id, |
| 335 scoped_ptr<DiscoverySessionOptions> options, | |
| 303 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | 336 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { |
| 304 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 337 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 305 discovery_session->Stop( | 338 discovery_session->Stop( |
| 306 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStopped, | 339 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStopped, |
| 307 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 340 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
| 341 base::Passed(&options)), | |
| 308 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStoppedError, | 342 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStoppedError, |
| 309 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 343 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
| 310 } | 344 } |
| 311 | 345 |
| 312 void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, | 346 // Defined at |
| 313 int request_id) { | 347 // https://webbluetoothcg.github.io/web-bluetooth/#dfn-matches-a-filter |
|
scheib
2015/06/15 23:47:21
Please update https://github.com/WebBluetoothChrom
Jeffrey Yasskin
2015/06/16 00:48:10
Done: https://github.com/WebBluetoothChrome/web-bl
| |
| 348 static bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids, | |
| 349 const BluetoothScanFilter& filter) { | |
| 350 if (filter.services.empty()) | |
| 351 return false; | |
| 352 for (const BluetoothUUID& service : filter.services) { | |
| 353 if (!ContainsKey(device_uuids, service)) { | |
| 354 return false; | |
| 355 } | |
| 356 } | |
| 357 return true; | |
| 358 } | |
| 359 | |
| 360 static bool MatchesFilters(const device::BluetoothDevice& device, | |
| 361 const std::vector<BluetoothScanFilter>& filters) { | |
| 362 const std::vector<BluetoothUUID>& device_uuid_list = device.GetUUIDs(); | |
| 363 const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(), | |
| 364 device_uuid_list.end()); | |
| 365 for (const BluetoothScanFilter& filter : filters) { | |
| 366 if (MatchesFilter(device_uuids, filter)) { | |
| 367 return true; | |
| 368 } | |
| 369 } | |
| 370 return false; | |
| 371 } | |
|
scheib
2015/06/15 23:47:21
Follow with blank line.
Jeffrey Yasskin
2015/06/16 00:48:10
Done.
| |
| 372 void BluetoothDispatcherHost::OnDiscoverySessionStopped( | |
| 373 int thread_id, | |
| 374 int request_id, | |
| 375 scoped_ptr<DiscoverySessionOptions> options) { | |
| 314 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 376 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 315 BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); | 377 BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
| 316 if (devices.begin() == devices.end()) { | 378 for (device::BluetoothDevice* device : devices) { |
| 317 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, | 379 if (MatchesFilters(*device, options->filters)) { |
| 318 BluetoothError::NOT_FOUND)); | 380 content::BluetoothDevice device_ipc( |
| 319 } else { | 381 device->GetAddress(), // instance_id |
| 320 device::BluetoothDevice* device = *devices.begin(); | 382 device->GetName(), // name |
| 321 content::BluetoothDevice device_ipc( | 383 device->GetBluetoothClass(), // device_class |
| 322 device->GetAddress(), // instance_id | 384 device->GetVendorIDSource(), // vendor_id_source |
| 323 device->GetName(), // name | 385 device->GetVendorID(), // vendor_id |
| 324 device->GetBluetoothClass(), // device_class | 386 device->GetProductID(), // product_id |
| 325 device->GetVendorIDSource(), // vendor_id_source | 387 device->GetDeviceID(), // product_version |
| 326 device->GetVendorID(), // vendor_id | 388 device->IsPaired(), // paired |
| 327 device->GetProductID(), // product_id | 389 content::BluetoothDevice::UUIDsFromBluetoothUUIDs( |
| 328 device->GetDeviceID(), // product_version | 390 device->GetUUIDs())); // uuids |
| 329 device->IsPaired(), // paired | 391 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id, |
| 330 content::BluetoothDevice::UUIDsFromBluetoothUUIDs( | 392 device_ipc)); |
| 331 device->GetUUIDs())); // uuids | 393 return; |
| 332 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id, | 394 } |
| 333 device_ipc)); | |
| 334 } | 395 } |
| 396 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, | |
| 397 BluetoothError::NOT_FOUND)); | |
| 335 } | 398 } |
| 336 | 399 |
| 337 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id, | 400 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id, |
| 338 int request_id) { | 401 int request_id) { |
| 339 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 402 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 340 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError"; | 403 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError"; |
| 341 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, | 404 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, |
| 342 BluetoothError::NOT_FOUND)); | 405 BluetoothError::NOT_FOUND)); |
| 343 } | 406 } |
| 344 | 407 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 int thread_id, | 474 int thread_id, |
| 412 int request_id, | 475 int request_id, |
| 413 device::BluetoothGattService::GattErrorCode) { | 476 device::BluetoothGattService::GattErrorCode) { |
| 414 // TODO(ortuno): Send a different Error based on the GattErrorCode. | 477 // TODO(ortuno): Send a different Error based on the GattErrorCode. |
| 415 // http://crbug.com/499542 | 478 // http://crbug.com/499542 |
| 416 Send(new BluetoothMsg_ReadCharacteristicValueError(thread_id, request_id, | 479 Send(new BluetoothMsg_ReadCharacteristicValueError(thread_id, request_id, |
| 417 BluetoothError::NETWORK)); | 480 BluetoothError::NETWORK)); |
| 418 } | 481 } |
| 419 | 482 |
| 420 } // namespace content | 483 } // namespace content |
| OLD | NEW |