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

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

Issue 1848663002: bluetooth: Remove indicator only when there are no more devices connected (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@my-origin
Patch Set: Address nick's comments Created 4 years, 8 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 // 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/bluetooth/bluetooth_dispatcher_host.h ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698