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 // ID Not In Map Note: | 5 // ID Not In Map Note: |
| 6 // A service, characteristic, or descriptor ID not in the corresponding | 6 // A service, characteristic, or descriptor ID not in the corresponding |
| 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, | 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, |
| 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer | 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer |
| 9 // obtains the corresponding ID from this class and it will be added to the map | 9 // obtains the corresponding ID from this class and it will be added to the map |
| 10 // at that time. | 10 // at that time. |
| 11 | 11 |
| 12 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 12 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
| 13 | 13 |
| 14 #include <stddef.h> | 14 #include <stddef.h> |
| 15 | 15 |
| 16 #include <utility> | 16 #include <utility> |
| 17 | 17 |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/thread_task_runner_handle.h" | 21 #include "base/thread_task_runner_handle.h" |
| 22 #include "content/browser/bad_message.h" | 22 #include "content/browser/bad_message.h" |
| 23 #include "content/browser/bluetooth/bluetooth_blacklist.h" | 23 #include "content/browser/bluetooth/bluetooth_blacklist.h" |
| 24 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" | 24 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" |
| 25 #include "content/browser/frame_host/render_frame_host_impl.h" | 25 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 26 #include "content/browser/web_contents/web_contents_impl.h" | |
| 26 #include "content/public/browser/content_browser_client.h" | 27 #include "content/public/browser/content_browser_client.h" |
| 27 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 28 #include "content/public/browser/web_contents_delegate.h" | 29 #include "content/public/browser/web_contents_delegate.h" |
| 29 #include "device/bluetooth/bluetooth_adapter.h" | 30 #include "device/bluetooth/bluetooth_adapter.h" |
| 30 #include "device/bluetooth/bluetooth_adapter_factory.h" | 31 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 31 #include "device/bluetooth/bluetooth_device.h" | 32 #include "device/bluetooth/bluetooth_device.h" |
| 32 #include "device/bluetooth/bluetooth_discovery_session.h" | 33 #include "device/bluetooth/bluetooth_discovery_session.h" |
| 33 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 34 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 34 #include "device/bluetooth/bluetooth_gatt_service.h" | 35 #include "device/bluetooth/bluetooth_gatt_service.h" |
| 35 | 36 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 // directly, and change this to a reasonable discovery timeout. | 273 // directly, and change this to a reasonable discovery timeout. |
| 273 base::TimeDelta::FromSecondsD(current_delay_time_), | 274 base::TimeDelta::FromSecondsD(current_delay_time_), |
| 274 base::Bind(&BluetoothDispatcherHost::StopDeviceDiscovery, | 275 base::Bind(&BluetoothDispatcherHost::StopDeviceDiscovery, |
| 275 // base::Timer guarantees it won't call back after its | 276 // base::Timer guarantees it won't call back after its |
| 276 // destructor starts. | 277 // destructor starts. |
| 277 base::Unretained(this)), | 278 base::Unretained(this)), |
| 278 /*is_repeating=*/false), | 279 /*is_repeating=*/false), |
| 279 weak_ptr_factory_(this) { | 280 weak_ptr_factory_(this) { |
| 280 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 281 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 281 | 282 |
| 283 connected_devices_map_.reset(new ConnectedDevicesMap(render_process_id)); | |
| 284 | |
| 282 // Bind all future weak pointers to the UI thread. | 285 // Bind all future weak pointers to the UI thread. |
| 283 weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr(); | 286 weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr(); |
| 284 weak_ptr_on_ui_thread_.get(); // Associates with UI thread. | 287 weak_ptr_on_ui_thread_.get(); // Associates with UI thread. |
| 285 } | 288 } |
| 286 | 289 |
| 287 void BluetoothDispatcherHost::OnDestruct() const { | 290 void BluetoothDispatcherHost::OnDestruct() const { |
| 288 // See class comment: UI Thread Note. | 291 // See class comment: UI Thread Note. |
| 289 BrowserThread::DeleteOnUIThread::Destruct(this); | 292 BrowserThread::DeleteOnUIThread::Destruct(this); |
| 290 } | 293 } |
| 291 | 294 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 DCHECK(pending_primary_services_requests_.empty()); | 342 DCHECK(pending_primary_services_requests_.empty()); |
| 340 | 343 |
| 341 // The following data structures are cleaned up when a | 344 // The following data structures are cleaned up when a |
| 342 // device/service/characteristic is removed. | 345 // device/service/characteristic is removed. |
| 343 // Since this can happen after the test is done and the cleanup function is | 346 // Since this can happen after the test is done and the cleanup function is |
| 344 // called, we clean them here. | 347 // called, we clean them here. |
| 345 service_to_device_.clear(); | 348 service_to_device_.clear(); |
| 346 characteristic_to_service_.clear(); | 349 characteristic_to_service_.clear(); |
| 347 characteristic_id_to_notify_session_.clear(); | 350 characteristic_id_to_notify_session_.clear(); |
| 348 active_characteristic_threads_.clear(); | 351 active_characteristic_threads_.clear(); |
| 349 device_id_to_connection_map_.clear(); | 352 connected_devices_map_.reset(new ConnectedDevicesMap(render_process_id_)); |
| 350 allowed_devices_map_ = BluetoothAllowedDevicesMap(); | 353 allowed_devices_map_ = BluetoothAllowedDevicesMap(); |
| 351 } | 354 } |
| 352 | 355 |
| 353 set_adapter(std::move(mock_adapter)); | 356 set_adapter(std::move(mock_adapter)); |
| 354 } | 357 } |
| 355 | 358 |
| 356 BluetoothDispatcherHost::~BluetoothDispatcherHost() { | 359 BluetoothDispatcherHost::~BluetoothDispatcherHost() { |
| 357 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 360 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 358 // Clear adapter, releasing observer references. | 361 // Clear adapter, releasing observer references. |
| 359 set_adapter(scoped_refptr<device::BluetoothAdapter>()); | 362 set_adapter(scoped_refptr<device::BluetoothAdapter>()); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 service_uuid(service_uuid), | 447 service_uuid(service_uuid), |
| 445 func(func) {} | 448 func(func) {} |
| 446 ~PrimaryServicesRequest() {} | 449 ~PrimaryServicesRequest() {} |
| 447 | 450 |
| 448 int thread_id; | 451 int thread_id; |
| 449 int request_id; | 452 int request_id; |
| 450 std::string service_uuid; | 453 std::string service_uuid; |
| 451 CallingFunction func; | 454 CallingFunction func; |
| 452 }; | 455 }; |
| 453 | 456 |
| 457 BluetoothDispatcherHost::ConnectedDevicesMap::ConnectedDevicesMap( | |
| 458 int render_process_id) | |
| 459 : render_process_id_(render_process_id) {} | |
|
ncarter (slow)
2016/04/07 22:44:53
Add a blank line here, between the two functions (
ortuno
2016/04/07 22:49:03
Hmm git cl format didn't catch this one... Done.
| |
| 460 BluetoothDispatcherHost::ConnectedDevicesMap::~ConnectedDevicesMap() { | |
| 461 for (auto frame_id_device_id : frame_ids_device_ids_) { | |
| 462 DecrementBluetoothConnectedDeviceCount(frame_id_device_id.first); | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 bool BluetoothDispatcherHost::ConnectedDevicesMap::HasActiveConnection( | |
| 467 const std::string& device_id) { | |
| 468 auto connection_iter = device_id_to_connection_map_.find(device_id); | |
| 469 if (connection_iter != device_id_to_connection_map_.end()) { | |
| 470 return connection_iter->second->IsConnected(); | |
| 471 } | |
| 472 return false; | |
| 473 } | |
| 474 | |
| 475 void BluetoothDispatcherHost::ConnectedDevicesMap::InsertOrReplace( | |
| 476 int frame_routing_id, | |
| 477 const std::string& device_id, | |
| 478 scoped_ptr<device::BluetoothGattConnection> connection) { | |
| 479 auto connection_iter = device_id_to_connection_map_.find(device_id); | |
| 480 if (connection_iter == device_id_to_connection_map_.end()) { | |
| 481 IncrementBluetoothConnectedDeviceCount(frame_routing_id); | |
| 482 frame_ids_device_ids_.insert(std::make_pair(frame_routing_id, device_id)); | |
| 483 } else { | |
| 484 device_id_to_connection_map_.erase(connection_iter); | |
| 485 } | |
| 486 device_id_to_connection_map_[device_id] = std::move(connection); | |
| 487 } | |
| 488 | |
| 489 void BluetoothDispatcherHost::ConnectedDevicesMap::Remove( | |
| 490 int frame_routing_id, | |
| 491 const std::string& device_id) { | |
| 492 if (device_id_to_connection_map_.erase(device_id)) { | |
| 493 VLOG(1) << "Disconnecting device: " << device_id; | |
| 494 DecrementBluetoothConnectedDeviceCount(frame_routing_id); | |
| 495 frame_ids_device_ids_.erase(std::make_pair(frame_routing_id, device_id)); | |
| 496 } | |
| 497 } | |
| 498 | |
| 499 void BluetoothDispatcherHost::ConnectedDevicesMap:: | |
| 500 IncrementBluetoothConnectedDeviceCount(int frame_routing_id) { | |
| 501 RenderFrameHostImpl* render_frame_host = | |
| 502 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); | |
| 503 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | |
| 504 WebContents::FromRenderFrameHost(render_frame_host)); | |
| 505 if (web_contents) { | |
| 506 web_contents->IncrementBluetoothConnectedDeviceCount(); | |
| 507 } | |
| 508 } | |
| 509 | |
| 510 void BluetoothDispatcherHost::ConnectedDevicesMap:: | |
| 511 DecrementBluetoothConnectedDeviceCount(int frame_routing_id) { | |
| 512 RenderFrameHostImpl* render_frame_host = | |
| 513 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); | |
| 514 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | |
| 515 WebContents::FromRenderFrameHost(render_frame_host)); | |
| 516 if (web_contents) { | |
| 517 web_contents->DecrementBluetoothConnectedDeviceCount(); | |
| 518 } | |
| 519 } | |
|
ncarter (slow)
2016/04/07 22:44:53
Thanks for doing this.
| |
| 520 | |
| 454 void BluetoothDispatcherHost::set_adapter( | 521 void BluetoothDispatcherHost::set_adapter( |
| 455 scoped_refptr<device::BluetoothAdapter> adapter) { | 522 scoped_refptr<device::BluetoothAdapter> adapter) { |
| 456 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 523 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 457 if (adapter_.get()) | 524 if (adapter_.get()) |
| 458 adapter_->RemoveObserver(this); | 525 adapter_->RemoveObserver(this); |
| 459 adapter_ = adapter; | 526 adapter_ = adapter; |
| 460 if (adapter_.get()) | 527 if (adapter_.get()) |
| 461 adapter_->AddObserver(this); | 528 adapter_->AddObserver(this); |
| 462 } | 529 } |
| 463 | 530 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); | 735 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); |
| 669 | 736 |
| 670 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 737 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
| 671 RecordConnectGATTOutcome(query_result.outcome); | 738 RecordConnectGATTOutcome(query_result.outcome); |
| 672 Send(new BluetoothMsg_GATTServerConnectError(thread_id, request_id, | 739 Send(new BluetoothMsg_GATTServerConnectError(thread_id, request_id, |
| 673 query_result.GetWebError())); | 740 query_result.GetWebError())); |
| 674 return; | 741 return; |
| 675 } | 742 } |
| 676 | 743 |
| 677 // If we are already connected no need to connect again. | 744 // If we are already connected no need to connect again. |
| 678 auto connection_iter = device_id_to_connection_map_.find(device_id); | 745 if (connected_devices_map_->HasActiveConnection(device_id)) { |
| 679 if (connection_iter != device_id_to_connection_map_.end()) { | 746 VLOG(1) << "Already connected."; |
| 680 if (connection_iter->second->IsConnected()) { | 747 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id)); |
| 681 VLOG(1) << "Already connected."; | 748 return; |
| 682 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id)); | |
| 683 return; | |
| 684 } | |
| 685 } | 749 } |
| 686 | 750 |
| 687 query_result.device->CreateGattConnection( | 751 query_result.device->CreateGattConnection( |
| 688 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, | 752 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, |
| 689 weak_ptr_on_ui_thread_, thread_id, request_id, | 753 weak_ptr_on_ui_thread_, thread_id, request_id, |
| 690 frame_routing_id, device_id, start_time), | 754 frame_routing_id, device_id, start_time), |
| 691 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, | 755 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, |
| 692 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 756 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
| 693 start_time)); | 757 start_time)); |
| 694 } | 758 } |
| 695 | 759 |
| 696 void BluetoothDispatcherHost::OnGATTServerDisconnect( | 760 void BluetoothDispatcherHost::OnGATTServerDisconnect( |
| 697 int thread_id, | 761 int thread_id, |
| 698 int frame_routing_id, | 762 int frame_routing_id, |
| 699 const std::string& device_id) { | 763 const std::string& device_id) { |
| 700 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 764 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 701 RecordWebBluetoothFunctionCall( | 765 RecordWebBluetoothFunctionCall( |
| 702 UMAWebBluetoothFunction::REMOTE_GATT_SERVER_DISCONNECT); | 766 UMAWebBluetoothFunction::REMOTE_GATT_SERVER_DISCONNECT); |
| 703 | 767 |
| 704 // Frames can send a disconnect request after they've started navigating, | 768 // Frames can send a disconnect request after they've started navigating, |
| 705 // making calls to GetLastCommitted origin invalid. Because we still need | 769 // making calls to GetLastCommitted origin invalid. Because we still need |
| 706 // to disconnect the device, otherwise we would leave users with no other | 770 // to disconnect the device, otherwise we would leave users with no other |
| 707 // option to disconnect than closing the tab, we purposefully don't | 771 // option to disconnect than closing the tab, we purposefully don't |
| 708 // check if the frame has permission to interact with the device. | 772 // check if the frame has permission to interact with the device. |
| 709 | 773 |
| 710 RenderFrameHostImpl* render_frame_host = | |
| 711 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); | |
| 712 WebContents* web_contents = | |
| 713 WebContents::FromRenderFrameHost(render_frame_host); | |
| 714 if (web_contents) { | |
| 715 web_contents->SetBluetoothDeviceConnected(false); | |
| 716 } | |
| 717 | |
| 718 // The last BluetoothGattConnection for a device closes the connection when | 774 // The last BluetoothGattConnection for a device closes the connection when |
| 719 // it's destroyed. | 775 // it's destroyed. |
| 720 if (device_id_to_connection_map_.erase(device_id)) { | 776 |
| 721 VLOG(1) << "Disconnecting device: " << device_id; | 777 // This only catches disconnections from the renderer. If the device |
| 722 } | 778 // disconnects by itself, or the renderer frame has been deleted |
| 779 // due to navigation, we will not hide the indicator. | |
| 780 // TODO(ortuno): Once we move to Frame and Mojo we will be able | |
| 781 // to observe the frame's lifetime and hide the indicator when necessary. | |
| 782 // http://crbug.com/508771 | |
| 783 connected_devices_map_->Remove(frame_routing_id, device_id); | |
| 723 } | 784 } |
| 724 | 785 |
| 725 void BluetoothDispatcherHost::OnGetPrimaryService( | 786 void BluetoothDispatcherHost::OnGetPrimaryService( |
| 726 int thread_id, | 787 int thread_id, |
| 727 int request_id, | 788 int request_id, |
| 728 int frame_routing_id, | 789 int frame_routing_id, |
| 729 const std::string& device_id, | 790 const std::string& device_id, |
| 730 const std::string& service_uuid) { | 791 const std::string& service_uuid) { |
| 731 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 792 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 732 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 793 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1400 } | 1461 } |
| 1401 | 1462 |
| 1402 void BluetoothDispatcherHost::OnGATTConnectionCreated( | 1463 void BluetoothDispatcherHost::OnGATTConnectionCreated( |
| 1403 int thread_id, | 1464 int thread_id, |
| 1404 int request_id, | 1465 int request_id, |
| 1405 int frame_routing_id, | 1466 int frame_routing_id, |
| 1406 const std::string& device_id, | 1467 const std::string& device_id, |
| 1407 base::TimeTicks start_time, | 1468 base::TimeTicks start_time, |
| 1408 scoped_ptr<device::BluetoothGattConnection> connection) { | 1469 scoped_ptr<device::BluetoothGattConnection> connection) { |
| 1409 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1470 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1410 device_id_to_connection_map_[device_id] = std::move(connection); | |
| 1411 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); | 1471 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); |
| 1412 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); | 1472 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); |
| 1413 RenderFrameHostImpl* render_frame_host = | 1473 connected_devices_map_->InsertOrReplace(frame_routing_id, device_id, |
| 1414 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); | 1474 std::move(connection)); |
| 1415 WebContents* web_contents = | |
| 1416 WebContents::FromRenderFrameHost(render_frame_host); | |
| 1417 if (web_contents) { | |
| 1418 web_contents->SetBluetoothDeviceConnected(true); | |
| 1419 } | |
| 1420 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id)); | 1475 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id)); |
| 1421 } | 1476 } |
| 1422 | 1477 |
| 1423 void BluetoothDispatcherHost::OnCreateGATTConnectionError( | 1478 void BluetoothDispatcherHost::OnCreateGATTConnectionError( |
| 1424 int thread_id, | 1479 int thread_id, |
| 1425 int request_id, | 1480 int request_id, |
| 1426 const std::string& device_id, | 1481 const std::string& device_id, |
| 1427 base::TimeTicks start_time, | 1482 base::TimeTicks start_time, |
| 1428 device::BluetoothDevice::ConnectErrorCode error_code) { | 1483 device::BluetoothDevice::ConnectErrorCode error_code) { |
| 1429 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1484 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1616 | 1671 |
| 1617 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( | 1672 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( |
| 1618 int frame_routing_id, | 1673 int frame_routing_id, |
| 1619 const std::string& characteristic_instance_id) { | 1674 const std::string& characteristic_instance_id) { |
| 1620 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | 1675 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), |
| 1621 characteristic_instance_id) | 1676 characteristic_instance_id) |
| 1622 .outcome != CacheQueryOutcome::BAD_RENDERER; | 1677 .outcome != CacheQueryOutcome::BAD_RENDERER; |
| 1623 } | 1678 } |
| 1624 | 1679 |
| 1625 } // namespace content | 1680 } // namespace content |
| OLD | NEW |