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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |