| 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 |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |