 Chromium Code Reviews
 Chromium Code Reviews Issue 2637343002:
  Implement WebBluetooth descriptor.readValue()  (Closed)
    
  
    Issue 2637343002:
  Implement WebBluetooth descriptor.readValue()  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // ID Not In Map Note: A service, characteristic, or descriptor ID not in the | 5 // ID Not In Map Note: A service, characteristic, or descriptor ID not in the | 
| 6 // corresponding WebBluetoothServiceImpl map [service_id_to_device_address_, | 6 // corresponding WebBluetoothServiceImpl map [service_id_to_device_address_, | 
| 7 // characteristic_id_to_service_id_, descriptor_id_to_characteristic_id_] | 7 // characteristic_id_to_service_id_, descriptor_id_to_characteristic_id_] | 
| 8 // implies a hostile renderer because a renderer obtains the corresponding ID | 8 // implies a hostile renderer because a renderer obtains the corresponding ID | 
| 9 // from this class and it will be added to the map at that time. | 9 // from this class and it will be added to the map at that time. | 
| 10 | 10 | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 case CacheQueryOutcome::BAD_RENDERER: | 145 case CacheQueryOutcome::BAD_RENDERER: | 
| 146 NOTREACHED(); | 146 NOTREACHED(); | 
| 147 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 147 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 
| 148 case CacheQueryOutcome::NO_DEVICE: | 148 case CacheQueryOutcome::NO_DEVICE: | 
| 149 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 149 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 
| 150 case CacheQueryOutcome::NO_SERVICE: | 150 case CacheQueryOutcome::NO_SERVICE: | 
| 151 return blink::mojom::WebBluetoothResult::SERVICE_NO_LONGER_EXISTS; | 151 return blink::mojom::WebBluetoothResult::SERVICE_NO_LONGER_EXISTS; | 
| 152 case CacheQueryOutcome::NO_CHARACTERISTIC: | 152 case CacheQueryOutcome::NO_CHARACTERISTIC: | 
| 153 return blink::mojom::WebBluetoothResult:: | 153 return blink::mojom::WebBluetoothResult:: | 
| 154 CHARACTERISTIC_NO_LONGER_EXISTS; | 154 CHARACTERISTIC_NO_LONGER_EXISTS; | 
| 155 case CacheQueryOutcome::NO_DESCRIPTOR: | |
| 156 return blink::mojom::WebBluetoothResult::DESCRIPTOR_NO_LONGER_EXISTS; | |
| 155 } | 157 } | 
| 156 NOTREACHED(); | 158 NOTREACHED(); | 
| 157 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 159 return blink::mojom::WebBluetoothResult::DEVICE_NO_LONGER_IN_RANGE; | 
| 158 } | 160 } | 
| 159 | 161 | 
| 160 device::BluetoothDevice* device = nullptr; | 162 device::BluetoothDevice* device = nullptr; | 
| 161 device::BluetoothRemoteGattService* service = nullptr; | 163 device::BluetoothRemoteGattService* service = nullptr; | 
| 162 device::BluetoothRemoteGattCharacteristic* characteristic = nullptr; | 164 device::BluetoothRemoteGattCharacteristic* characteristic = nullptr; | 
| 165 device::BluetoothRemoteGattDescriptor* descriptor = nullptr; | |
| 163 CacheQueryOutcome outcome; | 166 CacheQueryOutcome outcome; | 
| 164 }; | 167 }; | 
| 165 | 168 | 
| 166 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | 169 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | 
| 167 RenderFrameHost* render_frame_host, | 170 RenderFrameHost* render_frame_host, | 
| 168 blink::mojom::WebBluetoothServiceRequest request) | 171 blink::mojom::WebBluetoothServiceRequest request) | 
| 169 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), | 172 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), | 
| 170 connected_devices_(new FrameConnectedBluetoothDevices(render_frame_host)), | 173 connected_devices_(new FrameConnectedBluetoothDevices(render_frame_host)), | 
| 171 render_frame_host_(render_frame_host), | 174 render_frame_host_(render_frame_host), | 
| 172 binding_(this, std::move(request)), | 175 binding_(this, std::move(request)), | 
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 // If the frame hasn't subscribed to notifications before we just | 733 // If the frame hasn't subscribed to notifications before we just | 
| 731 // run the callback. | 734 // run the callback. | 
| 732 callback.Run(); | 735 callback.Run(); | 
| 733 return; | 736 return; | 
| 734 } | 737 } | 
| 735 notify_session_iter->second->Stop(base::Bind( | 738 notify_session_iter->second->Stop(base::Bind( | 
| 736 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, | 739 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, | 
| 737 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); | 740 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); | 
| 738 } | 741 } | 
| 739 | 742 | 
| 743 void WebBluetoothServiceImpl::RemoteDescriptorReadValue( | |
| 744 const std::string& descriptor_instance_id, | |
| 745 const RemoteDescriptorReadValueCallback& callback) { | |
| 746 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 747 | |
| 748 const CacheQueryResult query_result = | |
| 749 QueryCacheForDescriptor(descriptor_instance_id); | |
| 750 | |
| 751 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
| 752 return; | |
| 753 } | |
| 754 | |
| 755 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | |
| 756 callback.Run(query_result.GetWebResult(), base::nullopt /* value */); | |
| 757 return; | |
| 758 } | |
| 759 | |
| 760 if (BluetoothBlocklist::Get().IsExcludedFromReads( | |
| 761 query_result.descriptor->GetUUID())) { | |
| 762 callback.Run(blink::mojom::WebBluetoothResult::BLOCKLISTED_READ, | |
| 763 base::nullopt /* value */); | |
| 764 return; | |
| 765 } | |
| 766 | |
| 767 query_result.descriptor->ReadRemoteDescriptor( | |
| 768 base::Bind(&WebBluetoothServiceImpl::OnDescriptorReadValueSuccess, | |
| 769 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 770 base::Bind(&WebBluetoothServiceImpl::OnDescriptorReadValueFailed, | |
| 771 weak_ptr_factory_.GetWeakPtr(), callback)); | |
| 772 } | |
| 773 | |
| 740 void WebBluetoothServiceImpl::RequestDeviceImpl( | 774 void WebBluetoothServiceImpl::RequestDeviceImpl( | 
| 741 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | 775 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | 
| 742 const RequestDeviceCallback& callback, | 776 const RequestDeviceCallback& callback, | 
| 743 device::BluetoothAdapter* adapter) { | 777 device::BluetoothAdapter* adapter) { | 
| 744 // requestDevice() can only be called when processing a user-gesture and any | 778 // requestDevice() can only be called when processing a user-gesture and any | 
| 745 // user gesture outside of a chooser should close the chooser. This does | 779 // user gesture outside of a chooser should close the chooser. This does | 
| 746 // not happen on all platforms so we don't DCHECK that the old one is closed. | 780 // not happen on all platforms so we don't DCHECK that the old one is closed. | 
| 747 // We destroy the old chooser before constructing the new one to make sure | 781 // We destroy the old chooser before constructing the new one to make sure | 
| 748 // they can't conflict. | 782 // they can't conflict. | 
| 749 device_chooser_controller_.reset(); | 783 device_chooser_controller_.reset(); | 
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 931 error_code, UMAGATTOperation::START_NOTIFICATIONS)); | 965 error_code, UMAGATTOperation::START_NOTIFICATIONS)); | 
| 932 } | 966 } | 
| 933 | 967 | 
| 934 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 968 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 
| 935 const std::string& characteristic_instance_id, | 969 const std::string& characteristic_instance_id, | 
| 936 const RemoteCharacteristicStopNotificationsCallback& callback) { | 970 const RemoteCharacteristicStopNotificationsCallback& callback) { | 
| 937 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 971 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 
| 938 callback.Run(); | 972 callback.Run(); | 
| 939 } | 973 } | 
| 940 | 974 | 
| 975 void WebBluetoothServiceImpl::OnDescriptorReadValueSuccess( | |
| 976 const RemoteDescriptorReadValueCallback& callback, | |
| 977 const std::vector<uint8_t>& value) { | |
| 978 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 
ortuno
2017/01/20 04:30:52
Add todo for metrics.
 
dougt
2017/01/23 21:40:35
Acknowledged.
There are probably a dozen places t
 | |
| 979 callback.Run(blink::mojom::WebBluetoothResult::SUCCESS, value); | |
| 980 } | |
| 981 | |
| 982 void WebBluetoothServiceImpl::OnDescriptorReadValueFailed( | |
| 983 const RemoteDescriptorReadValueCallback& callback, | |
| 984 device::BluetoothRemoteGattService::GattErrorCode error_code) { | |
| 985 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 986 // TODO(667319) We are reporting failures to UMA but not reporting successes. | |
| 987 callback.Run(TranslateGATTErrorAndRecord(error_code, | |
| 988 UMAGATTOperation::DESCRIPTOR_READ), | |
| 989 base::nullopt /* value */); | |
| 990 } | |
| 991 | |
| 941 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( | 992 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( | 
| 942 const WebBluetoothDeviceId& device_id) { | 993 const WebBluetoothDeviceId& device_id) { | 
| 943 const std::string& device_address = | 994 const std::string& device_address = | 
| 944 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); | 995 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); | 
| 945 if (device_address.empty()) { | 996 if (device_address.empty()) { | 
| 946 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | 997 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | 
| 947 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 998 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 
| 948 } | 999 } | 
| 949 | 1000 | 
| 950 CacheQueryResult result; | 1001 CacheQueryResult result; | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1013 result.characteristic = | 1064 result.characteristic = | 
| 1014 result.service->GetCharacteristic(characteristic_instance_id); | 1065 result.service->GetCharacteristic(characteristic_instance_id); | 
| 1015 | 1066 | 
| 1016 if (result.characteristic == nullptr) { | 1067 if (result.characteristic == nullptr) { | 
| 1017 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 1068 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 
| 1018 } | 1069 } | 
| 1019 | 1070 | 
| 1020 return result; | 1071 return result; | 
| 1021 } | 1072 } | 
| 1022 | 1073 | 
| 1074 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDescriptor( | |
| 1075 const std::string& descriptor_instance_id) { | |
| 1076 auto descriptor_iter = | |
| 1077 descriptor_id_to_characteristic_id_.find(descriptor_instance_id); | |
| 1078 | |
| 1079 // Kill the render, see "ID Not in Map Note" above. | |
| 1080 if (descriptor_iter == descriptor_id_to_characteristic_id_.end()) { | |
| 1081 CrashRendererAndClosePipe(bad_message::BDH_INVALID_DESCRIPTOR_ID); | |
| 1082 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
| 1083 } | |
| 1084 | |
| 1085 CacheQueryResult result = | |
| 1086 QueryCacheForCharacteristic(descriptor_iter->second); | |
| 1087 | |
| 1088 if (result.outcome != CacheQueryOutcome::SUCCESS) { | |
| 1089 return result; | |
| 1090 } | |
| 1091 | |
| 1092 result.descriptor = | |
| 1093 result.characteristic->GetDescriptor(descriptor_instance_id); | |
| 1094 | |
| 1095 if (result.descriptor == nullptr) { | |
| 1096 result.outcome = CacheQueryOutcome::NO_DESCRIPTOR; | |
| 1097 } | |
| 1098 | |
| 1099 return result; | |
| 1100 } | |
| 1101 | |
| 1023 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 1102 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 
| 1024 return render_frame_host_->GetProcess(); | 1103 return render_frame_host_->GetProcess(); | 
| 1025 } | 1104 } | 
| 1026 | 1105 | 
| 1027 device::BluetoothAdapter* WebBluetoothServiceImpl::GetAdapter() { | 1106 device::BluetoothAdapter* WebBluetoothServiceImpl::GetAdapter() { | 
| 1028 return BluetoothAdapterFactoryWrapper::Get().GetAdapter(this); | 1107 return BluetoothAdapterFactoryWrapper::Get().GetAdapter(this); | 
| 1029 } | 1108 } | 
| 1030 | 1109 | 
| 1031 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 1110 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 
| 1032 bad_message::BadMessageReason reason) { | 1111 bad_message::BadMessageReason reason) { | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1045 characteristic_id_to_service_id_.clear(); | 1124 characteristic_id_to_service_id_.clear(); | 
| 1046 service_id_to_device_address_.clear(); | 1125 service_id_to_device_address_.clear(); | 
| 1047 connected_devices_.reset( | 1126 connected_devices_.reset( | 
| 1048 new FrameConnectedBluetoothDevices(render_frame_host_)); | 1127 new FrameConnectedBluetoothDevices(render_frame_host_)); | 
| 1049 allowed_devices_map_ = BluetoothAllowedDevicesMap(); | 1128 allowed_devices_map_ = BluetoothAllowedDevicesMap(); | 
| 1050 device_chooser_controller_.reset(); | 1129 device_chooser_controller_.reset(); | 
| 1051 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this); | 1130 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this); | 
| 1052 } | 1131 } | 
| 1053 | 1132 | 
| 1054 } // namespace content | 1133 } // namespace content | 
| OLD | NEW |