Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: content/browser/bluetooth/bluetooth_dispatcher_host.cc

Issue 1172853004: Chromium side of RequestDeviceOptions implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: Be more paranoid about BluetoothUUID IPCs Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // NETWORK_ERROR Note: 5 // NETWORK_ERROR Note:
6 // When a device can't be found in the BluetoothAdapter, that generally 6 // When a device can't be found in the BluetoothAdapter, that generally
7 // indicates that it's gone out of range. We reject with a NetworkError in that 7 // indicates that it's gone out of range. We reject with a NetworkError in that
8 // case. 8 // case.
9 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-connectga tt 9 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-connectga tt
10 10
11 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" 11 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
12 12
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/bad_message.h" 15 #include "content/browser/bad_message.h"
16 #include "content/common/bluetooth/bluetooth_messages.h" 16 #include "content/common/bluetooth/bluetooth_messages.h"
17 #include "device/bluetooth/bluetooth_adapter.h" 17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_adapter_factory.h" 18 #include "device/bluetooth/bluetooth_adapter_factory.h"
19 #include "device/bluetooth/bluetooth_device.h" 19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_discovery_session.h" 20 #include "device/bluetooth/bluetooth_discovery_session.h"
21 #include "device/bluetooth/bluetooth_gatt_characteristic.h" 21 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
22 #include "device/bluetooth/bluetooth_gatt_service.h" 22 #include "device/bluetooth/bluetooth_gatt_service.h"
23 23
24 using device::BluetoothAdapter; 24 using device::BluetoothAdapter;
25 using device::BluetoothAdapterFactory; 25 using device::BluetoothAdapterFactory;
26 using device::BluetoothGattCharacteristic; 26 using device::BluetoothGattCharacteristic;
27 using device::BluetoothGattService; 27 using device::BluetoothGattService;
28 using device::BluetoothUUID;
28 29
29 namespace { 30 namespace {
30 31
31 // These types of errors aren't as common. We log them to understand 32 // These types of errors aren't as common. We log them to understand
32 // how common they are and if we need to investigate more. 33 // how common they are and if we need to investigate more.
33 enum class BluetoothGATTError { 34 enum class BluetoothGATTError {
34 UNKNOWN, 35 UNKNOWN,
35 FAILED, 36 FAILED,
36 IN_PROGRESS, 37 IN_PROGRESS,
37 NOT_PAIRED, 38 NOT_PAIRED,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 current_delay_time_ = kTestingDelayTime; 173 current_delay_time_ = kTestingDelayTime;
173 set_adapter(mock_adapter.Pass()); 174 set_adapter(mock_adapter.Pass());
174 } 175 }
175 176
176 BluetoothDispatcherHost::~BluetoothDispatcherHost() { 177 BluetoothDispatcherHost::~BluetoothDispatcherHost() {
177 DCHECK_CURRENTLY_ON(BrowserThread::UI); 178 DCHECK_CURRENTLY_ON(BrowserThread::UI);
178 // Clear adapter, releasing observer references. 179 // Clear adapter, releasing observer references.
179 set_adapter(scoped_refptr<device::BluetoothAdapter>()); 180 set_adapter(scoped_refptr<device::BluetoothAdapter>());
180 } 181 }
181 182
183 struct BluetoothDispatcherHost::DiscoverySessionOptions {
184 DiscoverySessionOptions(const std::vector<BluetoothScanFilter>& filters,
185 const std::vector<BluetoothUUID>& optional_services)
186 : filters(filters), optional_services(optional_services) {}
187
188 std::vector<BluetoothScanFilter> filters;
189 std::vector<BluetoothUUID> optional_services;
190 };
191
182 void BluetoothDispatcherHost::set_adapter( 192 void BluetoothDispatcherHost::set_adapter(
183 scoped_refptr<device::BluetoothAdapter> adapter) { 193 scoped_refptr<device::BluetoothAdapter> adapter) {
184 DCHECK_CURRENTLY_ON(BrowserThread::UI); 194 DCHECK_CURRENTLY_ON(BrowserThread::UI);
185 if (adapter_.get()) 195 if (adapter_.get())
186 adapter_->RemoveObserver(this); 196 adapter_->RemoveObserver(this);
187 adapter_ = adapter; 197 adapter_ = adapter;
188 if (adapter_.get()) 198 if (adapter_.get())
189 adapter_->AddObserver(this); 199 adapter_->AddObserver(this);
190 } 200 }
191 201
192 void BluetoothDispatcherHost::OnRequestDevice(int thread_id, int request_id) { 202 static scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter(
203 const std::vector<BluetoothScanFilter>& filters) {
204 std::set<BluetoothUUID> services;
205 for (const BluetoothScanFilter& filter : filters) {
206 services.insert(filter.services.begin(), filter.services.end());
207 }
208 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter(
209 new device::BluetoothDiscoveryFilter(
210 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL));
211 for (const BluetoothUUID& service : services) {
212 discovery_filter->AddUUID(service);
213 }
214 return discovery_filter.Pass();
215 }
216
217 void BluetoothDispatcherHost::OnRequestDevice(
218 int thread_id,
219 int request_id,
220 const std::vector<BluetoothScanFilter>& filters,
221 const std::vector<BluetoothUUID>& optional_services) {
193 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 222 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
194 // TODO(scheib): Filter devices by services: crbug.com/440594
195 // TODO(scheib): Device selection UI: crbug.com/436280 223 // TODO(scheib): Device selection UI: crbug.com/436280
196 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed. 224 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed.
197 if (adapter_.get()) { 225 if (adapter_.get()) {
198 adapter_->StartDiscoverySession( 226 adapter_->StartDiscoverySessionWithFilter(
227 ComputeScanFilter(filters),
199 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted, 228 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted,
200 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 229 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
230 base::Passed(make_scoped_ptr(new DiscoverySessionOptions(
231 filters, optional_services)))),
201 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError, 232 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError,
202 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 233 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
203 } else { 234 } else {
204 DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice."; 235 DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice.";
205 Send(new BluetoothMsg_RequestDeviceError( 236 Send(new BluetoothMsg_RequestDeviceError(
206 thread_id, request_id, BluetoothError::NOT_FOUND, kNoBluetoothAdapter)); 237 thread_id, request_id, BluetoothError::NOT_FOUND, kNoBluetoothAdapter));
207 } 238 }
208 return; 239 return;
209 } 240 }
210 241
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 characteristic->ReadRemoteCharacteristic( 401 characteristic->ReadRemoteCharacteristic(
371 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, 402 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead,
372 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 403 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
373 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, 404 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError,
374 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 405 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
375 } 406 }
376 407
377 void BluetoothDispatcherHost::OnDiscoverySessionStarted( 408 void BluetoothDispatcherHost::OnDiscoverySessionStarted(
378 int thread_id, 409 int thread_id,
379 int request_id, 410 int request_id,
411 scoped_ptr<DiscoverySessionOptions> options,
380 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 412 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
381 DCHECK_CURRENTLY_ON(BrowserThread::UI); 413 DCHECK_CURRENTLY_ON(BrowserThread::UI);
382 BrowserThread::PostDelayedTask( 414 BrowserThread::PostDelayedTask(
383 BrowserThread::UI, FROM_HERE, 415 BrowserThread::UI, FROM_HERE,
384 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession, 416 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession,
385 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, 417 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
386 base::Passed(&discovery_session)), 418 base::Passed(&options), base::Passed(&discovery_session)),
387 base::TimeDelta::FromSeconds(current_delay_time_)); 419 base::TimeDelta::FromSeconds(current_delay_time_));
388 } 420 }
389 421
390 void BluetoothDispatcherHost::OnDiscoverySessionStartedError(int thread_id, 422 void BluetoothDispatcherHost::OnDiscoverySessionStartedError(int thread_id,
391 int request_id) { 423 int request_id) {
392 DCHECK_CURRENTLY_ON(BrowserThread::UI); 424 DCHECK_CURRENTLY_ON(BrowserThread::UI);
393 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStartedError"; 425 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStartedError";
394 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, 426 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id,
395 BluetoothError::NOT_FOUND, 427 BluetoothError::NOT_FOUND,
396 kDiscoverySessionStartFailed)); 428 kDiscoverySessionStartFailed));
397 } 429 }
398 430
399 void BluetoothDispatcherHost::StopDiscoverySession( 431 void BluetoothDispatcherHost::StopDiscoverySession(
400 int thread_id, 432 int thread_id,
401 int request_id, 433 int request_id,
434 scoped_ptr<DiscoverySessionOptions> options,
402 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 435 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
403 DCHECK_CURRENTLY_ON(BrowserThread::UI); 436 DCHECK_CURRENTLY_ON(BrowserThread::UI);
404 discovery_session->Stop( 437 discovery_session->Stop(
405 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStopped, 438 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStopped,
406 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 439 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
440 base::Passed(&options)),
407 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStoppedError, 441 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStoppedError,
408 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 442 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
409 } 443 }
410 444
411 void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, 445 // Defined at
412 int request_id) { 446 // https://webbluetoothcg.github.io/web-bluetooth/#dfn-matches-a-filter
447 static bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids,
448 const BluetoothScanFilter& filter) {
449 if (filter.services.empty())
450 return false;
451 for (const BluetoothUUID& service : filter.services) {
452 if (!ContainsKey(device_uuids, service)) {
453 return false;
454 }
455 }
456 return true;
457 }
458
459 static bool MatchesFilters(const device::BluetoothDevice& device,
460 const std::vector<BluetoothScanFilter>& filters) {
461 const std::vector<BluetoothUUID>& device_uuid_list = device.GetUUIDs();
462 const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
463 device_uuid_list.end());
464 for (const BluetoothScanFilter& filter : filters) {
465 if (MatchesFilter(device_uuids, filter)) {
466 return true;
467 }
468 }
469 return false;
470 }
471 void BluetoothDispatcherHost::OnDiscoverySessionStopped(
472 int thread_id,
473 int request_id,
474 scoped_ptr<DiscoverySessionOptions> options) {
413 DCHECK_CURRENTLY_ON(BrowserThread::UI); 475 DCHECK_CURRENTLY_ON(BrowserThread::UI);
414 BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); 476 BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
415 if (devices.begin() == devices.end()) { 477 for (device::BluetoothDevice* device : devices) {
416 Send(new BluetoothMsg_RequestDeviceError( 478 if (MatchesFilters(*device, options->filters)) {
417 thread_id, request_id, BluetoothError::NOT_FOUND, kNoDevicesFound)); 479 content::BluetoothDevice device_ipc(
418 } else { 480 device->GetAddress(), // instance_id
419 device::BluetoothDevice* device = *devices.begin(); 481 device->GetName(), // name
420 content::BluetoothDevice device_ipc( 482 device->GetBluetoothClass(), // device_class
421 device->GetAddress(), // instance_id 483 device->GetVendorIDSource(), // vendor_id_source
422 device->GetName(), // name 484 device->GetVendorID(), // vendor_id
423 device->GetBluetoothClass(), // device_class 485 device->GetProductID(), // product_id
424 device->GetVendorIDSource(), // vendor_id_source 486 device->GetDeviceID(), // product_version
425 device->GetVendorID(), // vendor_id 487 device->IsPaired(), // paired
426 device->GetProductID(), // product_id 488 content::BluetoothDevice::UUIDsFromBluetoothUUIDs(
427 device->GetDeviceID(), // product_version 489 device->GetUUIDs())); // uuids
428 device->IsPaired(), // paired 490 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id,
429 content::BluetoothDevice::UUIDsFromBluetoothUUIDs( 491 device_ipc));
430 device->GetUUIDs())); // uuids 492 return;
431 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id, 493 }
432 device_ipc));
433 } 494 }
495 Send(new BluetoothMsg_RequestDeviceError(
496 thread_id, request_id, BluetoothError::NOT_FOUND, kNoDevicesFound));
434 } 497 }
435 498
436 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id, 499 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id,
437 int request_id) { 500 int request_id) {
438 DCHECK_CURRENTLY_ON(BrowserThread::UI); 501 DCHECK_CURRENTLY_ON(BrowserThread::UI);
439 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError"; 502 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError";
440 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, 503 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id,
441 BluetoothError::NOT_FOUND, 504 BluetoothError::NOT_FOUND,
442 kDiscoverySessionStopFailed)); 505 kDiscoverySessionStopFailed));
443 } 506 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 void BluetoothDispatcherHost::OnCharacteristicReadValueError( 575 void BluetoothDispatcherHost::OnCharacteristicReadValueError(
513 int thread_id, 576 int thread_id,
514 int request_id, 577 int request_id,
515 device::BluetoothGattService::GattErrorCode error_code) { 578 device::BluetoothGattService::GattErrorCode error_code) {
516 std::pair<BluetoothError, std::string> error = TranslateGATTError(error_code); 579 std::pair<BluetoothError, std::string> error = TranslateGATTError(error_code);
517 Send(new BluetoothMsg_ReadCharacteristicValueError( 580 Send(new BluetoothMsg_ReadCharacteristicValueError(
518 thread_id, request_id, error.first, error.second)); 581 thread_id, request_id, error.first, error.second));
519 } 582 }
520 583
521 } // namespace content 584 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698