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 // 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 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { | 192 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { |
193 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 193 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
194 bool handled = true; | 194 bool handled = true; |
195 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) | 195 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) |
196 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) | 196 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) |
197 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) | 197 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) |
198 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) | 198 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) |
199 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) | 199 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) |
200 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) | 200 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) |
201 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) | 201 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) |
| 202 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications) |
| 203 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications) |
202 IPC_MESSAGE_UNHANDLED(handled = false) | 204 IPC_MESSAGE_UNHANDLED(handled = false) |
203 IPC_END_MESSAGE_MAP() | 205 IPC_END_MESSAGE_MAP() |
204 return handled; | 206 return handled; |
205 } | 207 } |
206 | 208 |
207 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( | 209 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( |
208 scoped_refptr<device::BluetoothAdapter> mock_adapter) { | 210 scoped_refptr<device::BluetoothAdapter> mock_adapter) { |
209 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 211 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
210 current_delay_time_ = kTestingDelayTime; | 212 current_delay_time_ = kTestingDelayTime; |
211 // Reset the discovery session timer to use the new delay time. | 213 // Reset the discovery session timer to use the new delay time. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter( | 310 for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter( |
309 &request_device_sessions_); | 311 &request_device_sessions_); |
310 !iter.IsAtEnd(); iter.Advance()) { | 312 !iter.IsAtEnd(); iter.Advance()) { |
311 RequestDeviceSession* session = iter.GetCurrentValue(); | 313 RequestDeviceSession* session = iter.GetCurrentValue(); |
312 if (session->chooser) { | 314 if (session->chooser) { |
313 session->chooser->RemoveDevice(device->GetAddress()); | 315 session->chooser->RemoveDevice(device->GetAddress()); |
314 } | 316 } |
315 } | 317 } |
316 } | 318 } |
317 | 319 |
| 320 void BluetoothDispatcherHost::GattCharacteristicValueChanged( |
| 321 device::BluetoothAdapter* adapter, |
| 322 device::BluetoothGattCharacteristic* characteristic, |
| 323 const std::vector<uint8>& value) { |
| 324 // TODO(ortuno): Notify renderer the characteristic changed. |
| 325 // http://crbug.com/529560 |
| 326 VLOG(1) << "Characteristic updated."; |
| 327 } |
| 328 |
318 static scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( | 329 static scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( |
319 const std::vector<BluetoothScanFilter>& filters) { | 330 const std::vector<BluetoothScanFilter>& filters) { |
320 std::set<BluetoothUUID> services; | 331 std::set<BluetoothUUID> services; |
321 for (const BluetoothScanFilter& filter : filters) { | 332 for (const BluetoothScanFilter& filter : filters) { |
322 services.insert(filter.services.begin(), filter.services.end()); | 333 services.insert(filter.services.begin(), filter.services.end()); |
323 } | 334 } |
324 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( | 335 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( |
325 new device::BluetoothDiscoveryFilter( | 336 new device::BluetoothDiscoveryFilter( |
326 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); | 337 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); |
327 for (const BluetoothUUID& service : services) { | 338 for (const BluetoothUUID& service : services) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 WebBluetoothError::CharacteristicNoLongerExists)); | 689 WebBluetoothError::CharacteristicNoLongerExists)); |
679 return; | 690 return; |
680 } | 691 } |
681 characteristic->WriteRemoteCharacteristic( | 692 characteristic->WriteRemoteCharacteristic( |
682 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | 693 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, |
683 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 694 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
684 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | 695 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, |
685 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 696 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
686 } | 697 } |
687 | 698 |
| 699 void BluetoothDispatcherHost::OnStartNotifications( |
| 700 int thread_id, |
| 701 int request_id, |
| 702 const std::string& characteristic_instance_id) { |
| 703 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 704 RecordWebBluetoothFunctionCall( |
| 705 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
| 706 |
| 707 // Check if already subscribed to notifications. |
| 708 auto notify_session_iter = |
| 709 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
| 710 if (notify_session_iter != characteristic_id_to_notify_session_.end()) { |
| 711 Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id)); |
| 712 return; |
| 713 } |
| 714 |
| 715 // TODO(ortuno): Check if notify/indicate bit is set. |
| 716 |
| 717 auto characteristic_iter = |
| 718 characteristic_to_service_.find(characteristic_instance_id); |
| 719 // A characteristic_instance_id not in the map implies a hostile renderer |
| 720 // because a renderer obtains the characteristic id from this class and |
| 721 // it will be added to the map at that time. |
| 722 if (characteristic_iter == characteristic_to_service_.end()) { |
| 723 // Kill the renderer |
| 724 bad_message::ReceivedBadMessage(this, |
| 725 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
| 726 return; |
| 727 } |
| 728 |
| 729 const std::string& service_instance_id = characteristic_iter->second; |
| 730 |
| 731 auto device_iter = service_to_device_.find(service_instance_id); |
| 732 |
| 733 CHECK(device_iter != service_to_device_.end()); |
| 734 |
| 735 device::BluetoothDevice* device = |
| 736 adapter_->GetDevice(device_iter->second /* device_instance_id */); |
| 737 if (device == nullptr) { // See "NETWORK_ERROR Note" above. |
| 738 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_DEVICE); |
| 739 Send(new BluetoothMsg_StartNotificationsError( |
| 740 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); |
| 741 return; |
| 742 } |
| 743 |
| 744 BluetoothGattService* service = device->GetGattService(service_instance_id); |
| 745 if (service == nullptr) { |
| 746 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_SERVICE); |
| 747 Send(new BluetoothMsg_StartNotificationsError( |
| 748 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists)); |
| 749 return; |
| 750 } |
| 751 |
| 752 BluetoothGattCharacteristic* characteristic = |
| 753 service->GetCharacteristic(characteristic_instance_id); |
| 754 if (characteristic == nullptr) { |
| 755 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_CHARACTERISTIC); |
| 756 Send(new BluetoothMsg_StartNotificationsError( |
| 757 thread_id, request_id, |
| 758 WebBluetoothError::CharacteristicNoLongerExists)); |
| 759 return; |
| 760 } |
| 761 |
| 762 characteristic->StartNotifySession( |
| 763 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, |
| 764 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
| 765 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, |
| 766 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
| 767 } |
| 768 |
| 769 void BluetoothDispatcherHost::OnStopNotifications( |
| 770 int thread_id, |
| 771 int request_id, |
| 772 const std::string& characteristic_instance_id) { |
| 773 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 774 RecordWebBluetoothFunctionCall( |
| 775 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
| 776 |
| 777 auto notify_session_iter = |
| 778 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
| 779 |
| 780 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
| 781 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
| 782 return; |
| 783 } |
| 784 notify_session_iter->second->Stop( |
| 785 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, |
| 786 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
| 787 characteristic_instance_id)); |
| 788 } |
| 789 |
688 void BluetoothDispatcherHost::OnDiscoverySessionStarted( | 790 void BluetoothDispatcherHost::OnDiscoverySessionStarted( |
689 int chooser_id, | 791 int chooser_id, |
690 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | 792 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { |
691 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 793 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
692 VLOG(1) << "Started discovery session for " << chooser_id; | 794 VLOG(1) << "Started discovery session for " << chooser_id; |
693 if (RequestDeviceSession* session = | 795 if (RequestDeviceSession* session = |
694 request_device_sessions_.Lookup(chooser_id)) { | 796 request_device_sessions_.Lookup(chooser_id)) { |
695 session->discovery_session = discovery_session.Pass(); | 797 session->discovery_session = discovery_session.Pass(); |
696 | 798 |
697 // Arrange to stop discovery later. | 799 // Arrange to stop discovery later. |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 void BluetoothDispatcherHost::OnWriteValueFailed( | 1009 void BluetoothDispatcherHost::OnWriteValueFailed( |
908 int thread_id, | 1010 int thread_id, |
909 int request_id, | 1011 int request_id, |
910 device::BluetoothGattService::GattErrorCode error_code) { | 1012 device::BluetoothGattService::GattErrorCode error_code) { |
911 // TranslateGATTError calls RecordGATTOperationOutcome. | 1013 // TranslateGATTError calls RecordGATTOperationOutcome. |
912 Send(new BluetoothMsg_WriteCharacteristicValueError( | 1014 Send(new BluetoothMsg_WriteCharacteristicValueError( |
913 thread_id, request_id, | 1015 thread_id, request_id, |
914 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); | 1016 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); |
915 } | 1017 } |
916 | 1018 |
| 1019 void BluetoothDispatcherHost::OnStartNotifySessionSuccess( |
| 1020 int thread_id, |
| 1021 int request_id, |
| 1022 scoped_ptr<device::BluetoothGattNotifySession> notify_session) { |
| 1023 characteristic_id_to_notify_session_.insert( |
| 1024 notify_session->GetCharacteristicIdentifier(), notify_session.Pass()); |
| 1025 Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id)); |
| 1026 } |
| 1027 |
| 1028 void BluetoothDispatcherHost::OnStartNotifySessionFailed( |
| 1029 int thread_id, |
| 1030 int request_id, |
| 1031 device::BluetoothGattService::GattErrorCode error_code) { |
| 1032 // TranslateGATTError calls RecordGATTOperationOutcome. |
| 1033 Send(new BluetoothMsg_StartNotificationsError( |
| 1034 thread_id, request_id, |
| 1035 TranslateGATTError(error_code, UMAGATTOperation::START_NOTIFICATIONS))); |
| 1036 } |
| 1037 |
| 1038 void BluetoothDispatcherHost::OnStopNotifySession( |
| 1039 int thread_id, |
| 1040 int request_id, |
| 1041 const std::string& characteristic_instance_id) { |
| 1042 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
| 1043 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
| 1044 } |
| 1045 |
917 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { | 1046 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { |
918 NOTIMPLEMENTED(); | 1047 NOTIMPLEMENTED(); |
919 } | 1048 } |
920 | 1049 |
921 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { | 1050 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { |
922 NOTIMPLEMENTED(); | 1051 NOTIMPLEMENTED(); |
923 } | 1052 } |
924 | 1053 |
925 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { | 1054 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { |
926 NOTIMPLEMENTED(); | 1055 NOTIMPLEMENTED(); |
927 } | 1056 } |
928 | 1057 |
929 } // namespace content | 1058 } // namespace content |
OLD | NEW |