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

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

Issue 1334763002: bluetooth: Subscribe to notifications (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-origin
Patch Set: Fix global interface test Created 5 years, 2 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://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-conne ctgatt 9 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-conne ctgatt
10 10
11 // ID Not In Map Note:
12 // A service, characteristic, or descriptor ID not in the corresponding
13 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_,
14 // descriptor_to_characteristic_] implies a hostile renderer because a renderer
15 // obtains the corresponding ID from this class and it will be added to the map
16 // at that time.
17
11 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" 18 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
12 19
13 #include "base/bind.h" 20 #include "base/bind.h"
14 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
15 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
16 #include "base/thread_task_runner_handle.h" 23 #include "base/thread_task_runner_handle.h"
17 #include "content/browser/bad_message.h" 24 #include "content/browser/bad_message.h"
18 #include "content/browser/bluetooth/bluetooth_metrics.h" 25 #include "content/browser/bluetooth/bluetooth_metrics.h"
19 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" 26 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h"
20 #include "content/browser/frame_host/render_frame_host_impl.h" 27 #include "content/browser/frame_host/render_frame_host_impl.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { 204 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
198 DCHECK_CURRENTLY_ON(BrowserThread::UI); 205 DCHECK_CURRENTLY_ON(BrowserThread::UI);
199 bool handled = true; 206 bool handled = true;
200 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) 207 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message)
201 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) 208 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice)
202 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) 209 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT)
203 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) 210 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService)
204 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) 211 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic)
205 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) 212 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue)
206 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) 213 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue)
214 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications)
215 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications)
207 IPC_MESSAGE_UNHANDLED(handled = false) 216 IPC_MESSAGE_UNHANDLED(handled = false)
208 IPC_END_MESSAGE_MAP() 217 IPC_END_MESSAGE_MAP()
209 return handled; 218 return handled;
210 } 219 }
211 220
212 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( 221 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting(
213 scoped_refptr<device::BluetoothAdapter> mock_adapter) { 222 scoped_refptr<device::BluetoothAdapter> mock_adapter) {
214 DCHECK_CURRENTLY_ON(BrowserThread::UI); 223 DCHECK_CURRENTLY_ON(BrowserThread::UI);
215 current_delay_time_ = kTestingDelayTime; 224 current_delay_time_ = kTestingDelayTime;
216 // Reset the discovery session timer to use the new delay time. 225 // Reset the discovery session timer to use the new delay time.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter( 360 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter(
352 &request_device_sessions_); 361 &request_device_sessions_);
353 !iter.IsAtEnd(); iter.Advance()) { 362 !iter.IsAtEnd(); iter.Advance()) {
354 RequestDeviceSession* session = iter.GetCurrentValue(); 363 RequestDeviceSession* session = iter.GetCurrentValue();
355 if (session->chooser) { 364 if (session->chooser) {
356 session->chooser->RemoveDevice(device->GetAddress()); 365 session->chooser->RemoveDevice(device->GetAddress());
357 } 366 }
358 } 367 }
359 } 368 }
360 369
370 void BluetoothDispatcherHost::GattCharacteristicValueChanged(
371 device::BluetoothAdapter* adapter,
372 device::BluetoothGattCharacteristic* characteristic,
373 const std::vector<uint8>& value) {
374 // TODO(ortuno): Notify renderer the characteristic changed.
375 // http://crbug.com/529560
376 VLOG(1) << "Characteristic updated.";
377 }
378
361 void BluetoothDispatcherHost::OnRequestDevice( 379 void BluetoothDispatcherHost::OnRequestDevice(
362 int thread_id, 380 int thread_id,
363 int request_id, 381 int request_id,
364 int frame_routing_id, 382 int frame_routing_id,
365 const std::vector<BluetoothScanFilter>& filters, 383 const std::vector<BluetoothScanFilter>& filters,
366 const std::vector<BluetoothUUID>& optional_services) { 384 const std::vector<BluetoothUUID>& optional_services) {
367 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 385 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
368 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); 386 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE);
369 RecordRequestDeviceArguments(filters, optional_services); 387 RecordRequestDeviceArguments(filters, optional_services);
370 388
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 void BluetoothDispatcherHost::OnGetCharacteristic( 528 void BluetoothDispatcherHost::OnGetCharacteristic(
511 int thread_id, 529 int thread_id,
512 int request_id, 530 int request_id,
513 const std::string& service_instance_id, 531 const std::string& service_instance_id,
514 const std::string& characteristic_uuid) { 532 const std::string& characteristic_uuid) {
515 DCHECK_CURRENTLY_ON(BrowserThread::UI); 533 DCHECK_CURRENTLY_ON(BrowserThread::UI);
516 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); 534 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
517 RecordGetCharacteristicCharacteristic(characteristic_uuid); 535 RecordGetCharacteristicCharacteristic(characteristic_uuid);
518 536
519 auto device_iter = service_to_device_.find(service_instance_id); 537 auto device_iter = service_to_device_.find(service_instance_id);
520 // A service_instance_id not in the map implies a hostile renderer 538 // Kill the renderer, see "ID Not In Map Note" above.
521 // because a renderer obtains the service id from this class and
522 // it will be added to the map at that time.
523 if (device_iter == service_to_device_.end()) { 539 if (device_iter == service_to_device_.end()) {
524 // Kill the renderer
525 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); 540 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
526 return; 541 return;
527 } 542 }
528 543
529 // TODO(ortuno): Check if domain has access to device. 544 // TODO(ortuno): Check if domain has access to device.
530 // https://crbug.com/493459 545 // https://crbug.com/493459
531 device::BluetoothDevice* device = 546 device::BluetoothDevice* device =
532 adapter_->GetDevice(device_iter->second /* device_instance_id */); 547 adapter_->GetDevice(device_iter->second /* device_instance_id */);
533 548
534 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 549 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 void BluetoothDispatcherHost::OnReadValue( 593 void BluetoothDispatcherHost::OnReadValue(
579 int thread_id, 594 int thread_id,
580 int request_id, 595 int request_id,
581 const std::string& characteristic_instance_id) { 596 const std::string& characteristic_instance_id) {
582 DCHECK_CURRENTLY_ON(BrowserThread::UI); 597 DCHECK_CURRENTLY_ON(BrowserThread::UI);
583 RecordWebBluetoothFunctionCall( 598 RecordWebBluetoothFunctionCall(
584 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); 599 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
585 600
586 auto characteristic_iter = 601 auto characteristic_iter =
587 characteristic_to_service_.find(characteristic_instance_id); 602 characteristic_to_service_.find(characteristic_instance_id);
588 // A characteristic_instance_id not in the map implies a hostile renderer 603
589 // because a renderer obtains the characteristic id from this class and 604 // Kill the renderer, see "ID Not In Map Note" above.
590 // it will be added to the map at that time.
591 if (characteristic_iter == characteristic_to_service_.end()) { 605 if (characteristic_iter == characteristic_to_service_.end()) {
592 // Kill the renderer
593 bad_message::ReceivedBadMessage(this, 606 bad_message::ReceivedBadMessage(this,
594 bad_message::BDH_INVALID_CHARACTERISTIC_ID); 607 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
595 return; 608 return;
596 } 609 }
597 const std::string& service_instance_id = characteristic_iter->second; 610 const std::string& service_instance_id = characteristic_iter->second;
598 611
599 auto device_iter = service_to_device_.find(service_instance_id); 612 auto device_iter = service_to_device_.find(service_instance_id);
600 613
601 CHECK(device_iter != service_to_device_.end()); 614 CHECK(device_iter != service_to_device_.end());
602 615
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 // get a value with length > 512, we can assume it's a hostile 663 // get a value with length > 512, we can assume it's a hostile
651 // renderer and kill it. 664 // renderer and kill it.
652 if (value.size() > 512) { 665 if (value.size() > 512) {
653 bad_message::ReceivedBadMessage( 666 bad_message::ReceivedBadMessage(
654 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); 667 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH);
655 return; 668 return;
656 } 669 }
657 670
658 auto characteristic_iter = 671 auto characteristic_iter =
659 characteristic_to_service_.find(characteristic_instance_id); 672 characteristic_to_service_.find(characteristic_instance_id);
660 // A characteristic_instance_id not in the map implies a hostile renderer 673
661 // because a renderer obtains the characteristic id from this class and 674 // Kill the renderer, see "ID Not In Map Note" above.
662 // it will be added to the map at that time.
663 if (characteristic_iter == characteristic_to_service_.end()) { 675 if (characteristic_iter == characteristic_to_service_.end()) {
664 bad_message::ReceivedBadMessage(this, 676 bad_message::ReceivedBadMessage(this,
665 bad_message::BDH_INVALID_CHARACTERISTIC_ID); 677 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
666 return; 678 return;
667 } 679 }
668 const std::string& service_instance_id = characteristic_iter->second; 680 const std::string& service_instance_id = characteristic_iter->second;
669 681
670 auto device_iter = service_to_device_.find(service_instance_id); 682 auto device_iter = service_to_device_.find(service_instance_id);
671 683
672 CHECK(device_iter != service_to_device_.end()); 684 CHECK(device_iter != service_to_device_.end());
(...skipping 25 matching lines...) Expand all
698 WebBluetoothError::CharacteristicNoLongerExists)); 710 WebBluetoothError::CharacteristicNoLongerExists));
699 return; 711 return;
700 } 712 }
701 characteristic->WriteRemoteCharacteristic( 713 characteristic->WriteRemoteCharacteristic(
702 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, 714 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
703 weak_ptr_on_ui_thread_, thread_id, request_id), 715 weak_ptr_on_ui_thread_, thread_id, request_id),
704 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, 716 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
705 weak_ptr_on_ui_thread_, thread_id, request_id)); 717 weak_ptr_on_ui_thread_, thread_id, request_id));
706 } 718 }
707 719
720 void BluetoothDispatcherHost::OnStartNotifications(
721 int thread_id,
722 int request_id,
723 const std::string& characteristic_instance_id) {
724 DCHECK_CURRENTLY_ON(BrowserThread::UI);
725 RecordWebBluetoothFunctionCall(
726 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
727
728 // BluetoothDispatcher will never send a request for a characteristic
729 // already subscribed to notifications.
730 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
731 characteristic_id_to_notify_session_.end()) {
732 bad_message::ReceivedBadMessage(
733 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
734 return;
735 }
736
737 // TODO(ortuno): Check if notify/indicate bit is set.
738 // http://crbug.com/538869
739
740 auto characteristic_iter =
741 characteristic_to_service_.find(characteristic_instance_id);
742
743 // Kill the renderer, see "ID Not In Map Note" above.
744 if (characteristic_iter == characteristic_to_service_.end()) {
745 bad_message::ReceivedBadMessage(this,
746 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
747 return;
748 }
749
750 const std::string& service_instance_id = characteristic_iter->second;
751 auto device_iter = service_to_device_.find(service_instance_id);
752 CHECK(device_iter != service_to_device_.end());
753
754 device::BluetoothDevice* device =
755 adapter_->GetDevice(device_iter->second /* device_instance_id */);
756 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
757 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_DEVICE);
758 Send(new BluetoothMsg_StartNotificationsError(
759 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
760 return;
761 }
762
763 BluetoothGattService* service = device->GetGattService(service_instance_id);
764 if (service == nullptr) {
765 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_SERVICE);
766 Send(new BluetoothMsg_StartNotificationsError(
767 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
768 return;
769 }
770
771 BluetoothGattCharacteristic* characteristic =
772 service->GetCharacteristic(characteristic_instance_id);
773 if (characteristic == nullptr) {
774 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_CHARACTERISTIC);
775 Send(new BluetoothMsg_StartNotificationsError(
776 thread_id, request_id,
777 WebBluetoothError::CharacteristicNoLongerExists));
778 return;
779 }
780
781 characteristic->StartNotifySession(
782 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
783 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
784 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
785 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
786 }
787
788 void BluetoothDispatcherHost::OnStopNotifications(
789 int thread_id,
790 int request_id,
791 const std::string& characteristic_instance_id) {
792 DCHECK_CURRENTLY_ON(BrowserThread::UI);
793 RecordWebBluetoothFunctionCall(
794 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS);
795
796 auto notify_session_iter =
797 characteristic_id_to_notify_session_.find(characteristic_instance_id);
798 if (notify_session_iter == characteristic_id_to_notify_session_.end()) {
799 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
800 return;
801 }
802 notify_session_iter->second->Stop(
803 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession,
804 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
805 characteristic_instance_id));
806 }
807
708 void BluetoothDispatcherHost::OnDiscoverySessionStarted( 808 void BluetoothDispatcherHost::OnDiscoverySessionStarted(
709 int chooser_id, 809 int chooser_id,
710 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 810 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
711 DCHECK_CURRENTLY_ON(BrowserThread::UI); 811 DCHECK_CURRENTLY_ON(BrowserThread::UI);
712 VLOG(1) << "Started discovery session for " << chooser_id; 812 VLOG(1) << "Started discovery session for " << chooser_id;
713 if (RequestDeviceSession* session = 813 if (RequestDeviceSession* session =
714 request_device_sessions_.Lookup(chooser_id)) { 814 request_device_sessions_.Lookup(chooser_id)) {
715 session->discovery_session = discovery_session.Pass(); 815 session->discovery_session = discovery_session.Pass();
716 816
717 // Arrange to stop discovery later. 817 // Arrange to stop discovery later.
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 int thread_id, 1039 int thread_id,
940 int request_id, 1040 int request_id,
941 device::BluetoothGattService::GattErrorCode error_code) { 1041 device::BluetoothGattService::GattErrorCode error_code) {
942 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1042 DCHECK_CURRENTLY_ON(BrowserThread::UI);
943 // TranslateGATTError calls RecordGATTOperationOutcome. 1043 // TranslateGATTError calls RecordGATTOperationOutcome.
944 Send(new BluetoothMsg_WriteCharacteristicValueError( 1044 Send(new BluetoothMsg_WriteCharacteristicValueError(
945 thread_id, request_id, 1045 thread_id, request_id,
946 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); 1046 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)));
947 } 1047 }
948 1048
1049 void BluetoothDispatcherHost::OnStartNotifySessionSuccess(
1050 int thread_id,
1051 int request_id,
1052 scoped_ptr<device::BluetoothGattNotifySession> notify_session) {
1053 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS);
1054
1055 characteristic_id_to_notify_session_.insert(
1056 notify_session->GetCharacteristicIdentifier(), notify_session.Pass());
1057 Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id));
1058 }
1059
1060 void BluetoothDispatcherHost::OnStartNotifySessionFailed(
1061 int thread_id,
1062 int request_id,
1063 device::BluetoothGattService::GattErrorCode error_code) {
1064 // TranslateGATTError calls RecordGATTOperationOutcome.
1065 Send(new BluetoothMsg_StartNotificationsError(
1066 thread_id, request_id,
1067 TranslateGATTError(error_code, UMAGATTOperation::START_NOTIFICATIONS)));
1068 }
1069
1070 void BluetoothDispatcherHost::OnStopNotifySession(
1071 int thread_id,
1072 int request_id,
1073 const std::string& characteristic_instance_id) {
1074 characteristic_id_to_notify_session_.erase(characteristic_instance_id);
1075 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
1076 }
1077
949 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { 1078 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
950 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1079 DCHECK_CURRENTLY_ON(BrowserThread::UI);
951 NOTIMPLEMENTED(); 1080 NOTIMPLEMENTED();
952 } 1081 }
953 1082
954 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { 1083 void BluetoothDispatcherHost::ShowBluetoothPairingLink() {
955 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1084 DCHECK_CURRENTLY_ON(BrowserThread::UI);
956 NOTIMPLEMENTED(); 1085 NOTIMPLEMENTED();
957 } 1086 }
958 1087
959 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { 1088 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() {
960 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1089 DCHECK_CURRENTLY_ON(BrowserThread::UI);
961 NOTIMPLEMENTED(); 1090 NOTIMPLEMENTED();
962 } 1091 }
963 1092
964 } // namespace content 1093 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/bluetooth/bluetooth_dispatcher_host.h ('k') | content/browser/bluetooth/bluetooth_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698