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

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: Fix format" 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) {}
460
461 BluetoothDispatcherHost::ConnectedDevicesMap::~ConnectedDevicesMap() {
462 for (auto frame_id_device_id : frame_ids_device_ids_) {
463 DecrementBluetoothConnectedDeviceCount(frame_id_device_id.first);
464 }
465 }
466
467 bool BluetoothDispatcherHost::ConnectedDevicesMap::HasActiveConnection(
468 const std::string& device_id) {
469 auto connection_iter = device_id_to_connection_map_.find(device_id);
470 if (connection_iter != device_id_to_connection_map_.end()) {
471 return connection_iter->second->IsConnected();
472 }
473 return false;
474 }
475
476 void BluetoothDispatcherHost::ConnectedDevicesMap::InsertOrReplace(
477 int frame_routing_id,
478 const std::string& device_id,
479 scoped_ptr<device::BluetoothGattConnection> connection) {
480 auto connection_iter = device_id_to_connection_map_.find(device_id);
481 if (connection_iter == device_id_to_connection_map_.end()) {
482 IncrementBluetoothConnectedDeviceCount(frame_routing_id);
483 frame_ids_device_ids_.insert(std::make_pair(frame_routing_id, device_id));
484 } else {
485 device_id_to_connection_map_.erase(connection_iter);
486 }
487 device_id_to_connection_map_[device_id] = std::move(connection);
488 }
489
490 void BluetoothDispatcherHost::ConnectedDevicesMap::Remove(
491 int frame_routing_id,
492 const std::string& device_id) {
493 if (device_id_to_connection_map_.erase(device_id)) {
494 VLOG(1) << "Disconnecting device: " << device_id;
495 DecrementBluetoothConnectedDeviceCount(frame_routing_id);
496 frame_ids_device_ids_.erase(std::make_pair(frame_routing_id, device_id));
497 }
498 }
499
500 void BluetoothDispatcherHost::ConnectedDevicesMap::
501 IncrementBluetoothConnectedDeviceCount(int frame_routing_id) {
502 RenderFrameHostImpl* render_frame_host =
503 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id);
504 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
505 WebContents::FromRenderFrameHost(render_frame_host));
506 if (web_contents) {
507 web_contents->IncrementBluetoothConnectedDeviceCount();
508 }
509 }
510
511 void BluetoothDispatcherHost::ConnectedDevicesMap::
512 DecrementBluetoothConnectedDeviceCount(int frame_routing_id) {
513 RenderFrameHostImpl* render_frame_host =
514 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id);
515 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
516 WebContents::FromRenderFrameHost(render_frame_host));
517 if (web_contents) {
518 web_contents->DecrementBluetoothConnectedDeviceCount();
519 }
520 }
521
454 void BluetoothDispatcherHost::set_adapter( 522 void BluetoothDispatcherHost::set_adapter(
455 scoped_refptr<device::BluetoothAdapter> adapter) { 523 scoped_refptr<device::BluetoothAdapter> adapter) {
456 DCHECK_CURRENTLY_ON(BrowserThread::UI); 524 DCHECK_CURRENTLY_ON(BrowserThread::UI);
457 if (adapter_.get()) 525 if (adapter_.get())
458 adapter_->RemoveObserver(this); 526 adapter_->RemoveObserver(this);
459 adapter_ = adapter; 527 adapter_ = adapter;
460 if (adapter_.get()) 528 if (adapter_.get())
461 adapter_->AddObserver(this); 529 adapter_->AddObserver(this);
462 } 530 }
463 531
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); 736 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id);
669 737
670 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { 738 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
671 RecordConnectGATTOutcome(query_result.outcome); 739 RecordConnectGATTOutcome(query_result.outcome);
672 Send(new BluetoothMsg_GATTServerConnectError(thread_id, request_id, 740 Send(new BluetoothMsg_GATTServerConnectError(thread_id, request_id,
673 query_result.GetWebError())); 741 query_result.GetWebError()));
674 return; 742 return;
675 } 743 }
676 744
677 // If we are already connected no need to connect again. 745 // If we are already connected no need to connect again.
678 auto connection_iter = device_id_to_connection_map_.find(device_id); 746 if (connected_devices_map_->HasActiveConnection(device_id)) {
679 if (connection_iter != device_id_to_connection_map_.end()) { 747 VLOG(1) << "Already connected.";
680 if (connection_iter->second->IsConnected()) { 748 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id));
681 VLOG(1) << "Already connected."; 749 return;
682 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id));
683 return;
684 }
685 } 750 }
686 751
687 query_result.device->CreateGattConnection( 752 query_result.device->CreateGattConnection(
688 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, 753 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated,
689 weak_ptr_on_ui_thread_, thread_id, request_id, 754 weak_ptr_on_ui_thread_, thread_id, request_id,
690 frame_routing_id, device_id, start_time), 755 frame_routing_id, device_id, start_time),
691 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, 756 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError,
692 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, 757 weak_ptr_on_ui_thread_, thread_id, request_id, device_id,
693 start_time)); 758 start_time));
694 } 759 }
695 760
696 void BluetoothDispatcherHost::OnGATTServerDisconnect( 761 void BluetoothDispatcherHost::OnGATTServerDisconnect(
697 int thread_id, 762 int thread_id,
698 int frame_routing_id, 763 int frame_routing_id,
699 const std::string& device_id) { 764 const std::string& device_id) {
700 DCHECK_CURRENTLY_ON(BrowserThread::UI); 765 DCHECK_CURRENTLY_ON(BrowserThread::UI);
701 RecordWebBluetoothFunctionCall( 766 RecordWebBluetoothFunctionCall(
702 UMAWebBluetoothFunction::REMOTE_GATT_SERVER_DISCONNECT); 767 UMAWebBluetoothFunction::REMOTE_GATT_SERVER_DISCONNECT);
703 768
704 // Frames can send a disconnect request after they've started navigating, 769 // Frames can send a disconnect request after they've started navigating,
705 // making calls to GetLastCommitted origin invalid. Because we still need 770 // making calls to GetLastCommitted origin invalid. Because we still need
706 // to disconnect the device, otherwise we would leave users with no other 771 // to disconnect the device, otherwise we would leave users with no other
707 // option to disconnect than closing the tab, we purposefully don't 772 // option to disconnect than closing the tab, we purposefully don't
708 // check if the frame has permission to interact with the device. 773 // check if the frame has permission to interact with the device.
709 774
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 775 // The last BluetoothGattConnection for a device closes the connection when
719 // it's destroyed. 776 // it's destroyed.
720 if (device_id_to_connection_map_.erase(device_id)) { 777
721 VLOG(1) << "Disconnecting device: " << device_id; 778 // This only catches disconnections from the renderer. If the device
722 } 779 // disconnects by itself, or the renderer frame has been deleted
780 // due to navigation, we will not hide the indicator.
781 // TODO(ortuno): Once we move to Frame and Mojo we will be able
782 // to observe the frame's lifetime and hide the indicator when necessary.
783 // http://crbug.com/508771
784 connected_devices_map_->Remove(frame_routing_id, device_id);
723 } 785 }
724 786
725 void BluetoothDispatcherHost::OnGetPrimaryService( 787 void BluetoothDispatcherHost::OnGetPrimaryService(
726 int thread_id, 788 int thread_id,
727 int request_id, 789 int request_id,
728 int frame_routing_id, 790 int frame_routing_id,
729 const std::string& device_id, 791 const std::string& device_id,
730 const std::string& service_uuid) { 792 const std::string& service_uuid) {
731 DCHECK_CURRENTLY_ON(BrowserThread::UI); 793 DCHECK_CURRENTLY_ON(BrowserThread::UI);
732 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); 794 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE);
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 } 1462 }
1401 1463
1402 void BluetoothDispatcherHost::OnGATTConnectionCreated( 1464 void BluetoothDispatcherHost::OnGATTConnectionCreated(
1403 int thread_id, 1465 int thread_id,
1404 int request_id, 1466 int request_id,
1405 int frame_routing_id, 1467 int frame_routing_id,
1406 const std::string& device_id, 1468 const std::string& device_id,
1407 base::TimeTicks start_time, 1469 base::TimeTicks start_time,
1408 scoped_ptr<device::BluetoothGattConnection> connection) { 1470 scoped_ptr<device::BluetoothGattConnection> connection) {
1409 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1471 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1410 device_id_to_connection_map_[device_id] = std::move(connection);
1411 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); 1472 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time);
1412 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); 1473 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS);
1413 RenderFrameHostImpl* render_frame_host = 1474 connected_devices_map_->InsertOrReplace(frame_routing_id, device_id,
1414 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); 1475 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)); 1476 Send(new BluetoothMsg_GATTServerConnectSuccess(thread_id, request_id));
1421 } 1477 }
1422 1478
1423 void BluetoothDispatcherHost::OnCreateGATTConnectionError( 1479 void BluetoothDispatcherHost::OnCreateGATTConnectionError(
1424 int thread_id, 1480 int thread_id,
1425 int request_id, 1481 int request_id,
1426 const std::string& device_id, 1482 const std::string& device_id,
1427 base::TimeTicks start_time, 1483 base::TimeTicks start_time,
1428 device::BluetoothDevice::ConnectErrorCode error_code) { 1484 device::BluetoothDevice::ConnectErrorCode error_code) {
1429 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1485 DCHECK_CURRENTLY_ON(BrowserThread::UI);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 1672
1617 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( 1673 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance(
1618 int frame_routing_id, 1674 int frame_routing_id,
1619 const std::string& characteristic_instance_id) { 1675 const std::string& characteristic_instance_id) {
1620 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), 1676 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id),
1621 characteristic_instance_id) 1677 characteristic_instance_id)
1622 .outcome != CacheQueryOutcome::BAD_RENDERER; 1678 .outcome != CacheQueryOutcome::BAD_RENDERER;
1623 } 1679 }
1624 1680
1625 } // namespace content 1681 } // 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