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

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: Wait for stop request to finish 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { 199 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
193 DCHECK_CURRENTLY_ON(BrowserThread::UI); 200 DCHECK_CURRENTLY_ON(BrowserThread::UI);
194 bool handled = true; 201 bool handled = true;
195 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) 202 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message)
196 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) 203 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice)
197 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) 204 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT)
198 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) 205 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService)
199 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) 206 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic)
200 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) 207 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue)
201 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) 208 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue)
209 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications)
210 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications)
202 IPC_MESSAGE_UNHANDLED(handled = false) 211 IPC_MESSAGE_UNHANDLED(handled = false)
203 IPC_END_MESSAGE_MAP() 212 IPC_END_MESSAGE_MAP()
204 return handled; 213 return handled;
205 } 214 }
206 215
207 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( 216 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting(
208 scoped_refptr<device::BluetoothAdapter> mock_adapter) { 217 scoped_refptr<device::BluetoothAdapter> mock_adapter) {
209 DCHECK_CURRENTLY_ON(BrowserThread::UI); 218 DCHECK_CURRENTLY_ON(BrowserThread::UI);
210 current_delay_time_ = kTestingDelayTime; 219 current_delay_time_ = kTestingDelayTime;
211 // Reset the discovery session timer to use the new delay time. 220 // Reset the discovery session timer to use the new delay time.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter( 349 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter(
341 &request_device_sessions_); 350 &request_device_sessions_);
342 !iter.IsAtEnd(); iter.Advance()) { 351 !iter.IsAtEnd(); iter.Advance()) {
343 RequestDeviceSession* session = iter.GetCurrentValue(); 352 RequestDeviceSession* session = iter.GetCurrentValue();
344 if (session->chooser) { 353 if (session->chooser) {
345 session->chooser->RemoveDevice(device->GetAddress()); 354 session->chooser->RemoveDevice(device->GetAddress());
346 } 355 }
347 } 356 }
348 } 357 }
349 358
359 void BluetoothDispatcherHost::GattCharacteristicValueChanged(
360 device::BluetoothAdapter* adapter,
361 device::BluetoothGattCharacteristic* characteristic,
362 const std::vector<uint8>& value) {
363 // TODO(ortuno): Notify renderer the characteristic changed.
364 // http://crbug.com/529560
365 VLOG(1) << "Characteristic updated.";
366 }
367
350 void BluetoothDispatcherHost::OnRequestDevice( 368 void BluetoothDispatcherHost::OnRequestDevice(
351 int thread_id, 369 int thread_id,
352 int request_id, 370 int request_id,
353 int frame_routing_id, 371 int frame_routing_id,
354 const std::vector<BluetoothScanFilter>& filters, 372 const std::vector<BluetoothScanFilter>& filters,
355 const std::vector<BluetoothUUID>& optional_services) { 373 const std::vector<BluetoothUUID>& optional_services) {
356 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 374 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
357 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); 375 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE);
358 RecordRequestDeviceArguments(filters, optional_services); 376 RecordRequestDeviceArguments(filters, optional_services);
359 377
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 void BluetoothDispatcherHost::OnGetCharacteristic( 517 void BluetoothDispatcherHost::OnGetCharacteristic(
500 int thread_id, 518 int thread_id,
501 int request_id, 519 int request_id,
502 const std::string& service_instance_id, 520 const std::string& service_instance_id,
503 const std::string& characteristic_uuid) { 521 const std::string& characteristic_uuid) {
504 DCHECK_CURRENTLY_ON(BrowserThread::UI); 522 DCHECK_CURRENTLY_ON(BrowserThread::UI);
505 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); 523 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
506 RecordGetCharacteristicCharacteristic(characteristic_uuid); 524 RecordGetCharacteristicCharacteristic(characteristic_uuid);
507 525
508 auto device_iter = service_to_device_.find(service_instance_id); 526 auto device_iter = service_to_device_.find(service_instance_id);
509 // A service_instance_id not in the map implies a hostile renderer 527 // Kill the renderer, see "ID Not In Map Note" above.
510 // because a renderer obtains the service id from this class and
511 // it will be added to the map at that time.
512 if (device_iter == service_to_device_.end()) { 528 if (device_iter == service_to_device_.end()) {
513 // Kill the renderer
514 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); 529 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
515 return; 530 return;
516 } 531 }
517 532
518 // TODO(ortuno): Check if domain has access to device. 533 // TODO(ortuno): Check if domain has access to device.
519 // https://crbug.com/493459 534 // https://crbug.com/493459
520 device::BluetoothDevice* device = 535 device::BluetoothDevice* device =
521 adapter_->GetDevice(device_iter->second /* device_instance_id */); 536 adapter_->GetDevice(device_iter->second /* device_instance_id */);
522 537
523 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 538 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 void BluetoothDispatcherHost::OnReadValue( 582 void BluetoothDispatcherHost::OnReadValue(
568 int thread_id, 583 int thread_id,
569 int request_id, 584 int request_id,
570 const std::string& characteristic_instance_id) { 585 const std::string& characteristic_instance_id) {
571 DCHECK_CURRENTLY_ON(BrowserThread::UI); 586 DCHECK_CURRENTLY_ON(BrowserThread::UI);
572 RecordWebBluetoothFunctionCall( 587 RecordWebBluetoothFunctionCall(
573 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); 588 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
574 589
575 auto characteristic_iter = 590 auto characteristic_iter =
576 characteristic_to_service_.find(characteristic_instance_id); 591 characteristic_to_service_.find(characteristic_instance_id);
577 // A characteristic_instance_id not in the map implies a hostile renderer 592
578 // because a renderer obtains the characteristic id from this class and 593 // Kill the renderer, see "ID Not In Map Note" above.
579 // it will be added to the map at that time.
580 if (characteristic_iter == characteristic_to_service_.end()) { 594 if (characteristic_iter == characteristic_to_service_.end()) {
581 // Kill the renderer
582 bad_message::ReceivedBadMessage(this, 595 bad_message::ReceivedBadMessage(this,
583 bad_message::BDH_INVALID_CHARACTERISTIC_ID); 596 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
584 return; 597 return;
585 } 598 }
586 const std::string& service_instance_id = characteristic_iter->second; 599 const std::string& service_instance_id = characteristic_iter->second;
587 600
588 auto device_iter = service_to_device_.find(service_instance_id); 601 auto device_iter = service_to_device_.find(service_instance_id);
589 602
590 CHECK(device_iter != service_to_device_.end()); 603 CHECK(device_iter != service_to_device_.end());
591 604
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 // get a value with length > 512, we can assume it's a hostile 652 // get a value with length > 512, we can assume it's a hostile
640 // renderer and kill it. 653 // renderer and kill it.
641 if (value.size() > 512) { 654 if (value.size() > 512) {
642 bad_message::ReceivedBadMessage( 655 bad_message::ReceivedBadMessage(
643 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); 656 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH);
644 return; 657 return;
645 } 658 }
646 659
647 auto characteristic_iter = 660 auto characteristic_iter =
648 characteristic_to_service_.find(characteristic_instance_id); 661 characteristic_to_service_.find(characteristic_instance_id);
649 // A characteristic_instance_id not in the map implies a hostile renderer 662
650 // because a renderer obtains the characteristic id from this class and 663 // Kill the renderer, see "ID Not In Map Note" above.
651 // it will be added to the map at that time.
652 if (characteristic_iter == characteristic_to_service_.end()) { 664 if (characteristic_iter == characteristic_to_service_.end()) {
653 bad_message::ReceivedBadMessage(this, 665 bad_message::ReceivedBadMessage(this,
654 bad_message::BDH_INVALID_CHARACTERISTIC_ID); 666 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
655 return; 667 return;
656 } 668 }
657 const std::string& service_instance_id = characteristic_iter->second; 669 const std::string& service_instance_id = characteristic_iter->second;
658 670
659 auto device_iter = service_to_device_.find(service_instance_id); 671 auto device_iter = service_to_device_.find(service_instance_id);
660 672
661 CHECK(device_iter != service_to_device_.end()); 673 CHECK(device_iter != service_to_device_.end());
(...skipping 25 matching lines...) Expand all
687 WebBluetoothError::CharacteristicNoLongerExists)); 699 WebBluetoothError::CharacteristicNoLongerExists));
688 return; 700 return;
689 } 701 }
690 characteristic->WriteRemoteCharacteristic( 702 characteristic->WriteRemoteCharacteristic(
691 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, 703 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
692 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 704 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
693 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, 705 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
694 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 706 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
695 } 707 }
696 708
709 void BluetoothDispatcherHost::OnStartNotifications(
710 int thread_id,
711 int request_id,
712 const std::string& characteristic_instance_id) {
713 DCHECK_CURRENTLY_ON(BrowserThread::UI);
714 RecordWebBluetoothFunctionCall(
715 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
716
717 // BluetoothDispatcher will never send a request for a characteristic
718 // already subscribed to notifications.
719 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
720 characteristic_id_to_notify_session_.end()) {
721 bad_message::ReceivedBadMessage(
722 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
723 return;
724 }
725
726 // TODO(ortuno): Check if notify/indicate bit is set.
727 // http://crbug.com/538869
728
729 auto characteristic_iter =
730 characteristic_to_service_.find(characteristic_instance_id);
731
732 // Kill the renderer, see "ID Not In Map Note" above.
733 if (characteristic_iter == characteristic_to_service_.end()) {
734 bad_message::ReceivedBadMessage(this,
735 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
736 return;
737 }
738
739 const std::string& service_instance_id = characteristic_iter->second;
740 auto device_iter = service_to_device_.find(service_instance_id);
741 CHECK(device_iter != service_to_device_.end());
742
743 device::BluetoothDevice* device =
744 adapter_->GetDevice(device_iter->second /* device_instance_id */);
745 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
746 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_DEVICE);
747 Send(new BluetoothMsg_StartNotificationsError(
748 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
749 return;
750 }
751
752 BluetoothGattService* service = device->GetGattService(service_instance_id);
753 if (service == nullptr) {
754 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_SERVICE);
755 Send(new BluetoothMsg_StartNotificationsError(
756 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
757 return;
758 }
759
760 BluetoothGattCharacteristic* characteristic =
761 service->GetCharacteristic(characteristic_instance_id);
762 if (characteristic == nullptr) {
763 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_CHARACTERISTIC);
764 Send(new BluetoothMsg_StartNotificationsError(
765 thread_id, request_id,
766 WebBluetoothError::CharacteristicNoLongerExists));
767 return;
768 }
769
770 characteristic->StartNotifySession(
771 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
772 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
773 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
774 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
775 }
776 void BluetoothDispatcherHost::OnStopNotifications(
777 int thread_id,
778 int request_id,
779 const std::string& characteristic_instance_id) {
780 DCHECK_CURRENTLY_ON(BrowserThread::UI);
781 RecordWebBluetoothFunctionCall(
782 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS);
783
784 auto notify_session_iter =
785 characteristic_id_to_notify_session_.find(characteristic_instance_id);
786 if (notify_session_iter == characteristic_id_to_notify_session_.end()) {
787 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
788 return;
789 }
790 notify_session_iter->second->Stop(
791 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession,
792 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
793 characteristic_instance_id));
794 }
795
697 void BluetoothDispatcherHost::OnDiscoverySessionStarted( 796 void BluetoothDispatcherHost::OnDiscoverySessionStarted(
698 int chooser_id, 797 int chooser_id,
699 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 798 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
700 DCHECK_CURRENTLY_ON(BrowserThread::UI); 799 DCHECK_CURRENTLY_ON(BrowserThread::UI);
701 VLOG(1) << "Started discovery session for " << chooser_id; 800 VLOG(1) << "Started discovery session for " << chooser_id;
702 if (RequestDeviceSession* session = 801 if (RequestDeviceSession* session =
703 request_device_sessions_.Lookup(chooser_id)) { 802 request_device_sessions_.Lookup(chooser_id)) {
704 session->discovery_session = discovery_session.Pass(); 803 session->discovery_session = discovery_session.Pass();
705 804
706 // Arrange to stop discovery later. 805 // Arrange to stop discovery later.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 void BluetoothDispatcherHost::OnWriteValueFailed( 1020 void BluetoothDispatcherHost::OnWriteValueFailed(
922 int thread_id, 1021 int thread_id,
923 int request_id, 1022 int request_id,
924 device::BluetoothGattService::GattErrorCode error_code) { 1023 device::BluetoothGattService::GattErrorCode error_code) {
925 // TranslateGATTError calls RecordGATTOperationOutcome. 1024 // TranslateGATTError calls RecordGATTOperationOutcome.
926 Send(new BluetoothMsg_WriteCharacteristicValueError( 1025 Send(new BluetoothMsg_WriteCharacteristicValueError(
927 thread_id, request_id, 1026 thread_id, request_id,
928 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); 1027 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)));
929 } 1028 }
930 1029
1030 void BluetoothDispatcherHost::OnStartNotifySessionSuccess(
1031 int thread_id,
1032 int request_id,
1033 scoped_ptr<device::BluetoothGattNotifySession> notify_session) {
1034 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS);
1035
1036 characteristic_id_to_notify_session_.insert(
1037 notify_session->GetCharacteristicIdentifier(), notify_session.Pass());
1038 Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id));
1039 }
1040
1041 void BluetoothDispatcherHost::OnStartNotifySessionFailed(
1042 int thread_id,
1043 int request_id,
1044 device::BluetoothGattService::GattErrorCode error_code) {
1045 // TranslateGATTError calls RecordGATTOperationOutcome.
1046 Send(new BluetoothMsg_StartNotificationsError(
1047 thread_id, request_id,
1048 TranslateGATTError(error_code, UMAGATTOperation::START_NOTIFICATIONS)));
1049 }
1050
1051 void BluetoothDispatcherHost::OnStopNotifySession(
1052 int thread_id,
1053 int request_id,
1054 const std::string& characteristic_instance_id) {
1055 characteristic_id_to_notify_session_.erase(characteristic_instance_id);
1056 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
1057 }
1058
931 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { 1059 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
932 NOTIMPLEMENTED(); 1060 NOTIMPLEMENTED();
933 } 1061 }
934 1062
935 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { 1063 void BluetoothDispatcherHost::ShowBluetoothPairingLink() {
936 NOTIMPLEMENTED(); 1064 NOTIMPLEMENTED();
937 } 1065 }
938 1066
939 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { 1067 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() {
940 NOTIMPLEMENTED(); 1068 NOTIMPLEMENTED();
941 } 1069 }
942 1070
943 } // namespace content 1071 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698