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: |
| 6 // A service, characteristic, or descriptor ID not in the corresponding |
| 7 // BluetoothDispatcherHost map [service_to_device_, |
| 8 // characteristic_id_to_service_id_, descriptor_to_characteristic_] implies a |
| 9 // hostile renderer because a renderer obtains the corresponding ID from this |
| 10 // class and it will be added to the map at that time. |
| 11 |
5 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" | 12 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" |
6 | 13 |
7 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
8 #include "content/browser/bluetooth/bluetooth_blacklist.h" | 15 #include "content/browser/bluetooth/bluetooth_blacklist.h" |
9 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 16 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
10 #include "content/browser/renderer_host/render_process_host_impl.h" | 17 #include "content/browser/renderer_host/render_process_host_impl.h" |
11 #include "content/public/browser/navigation_handle.h" | 18 #include "content/public/browser/navigation_handle.h" |
12 #include "content/public/browser/render_frame_host.h" | 19 #include "content/public/browser/render_frame_host.h" |
13 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" | 21 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" |
15 | 22 |
16 using device::BluetoothRemoteGattService; | |
17 | |
18 namespace content { | 23 namespace content { |
19 | 24 |
20 namespace { | 25 namespace { |
21 | 26 |
22 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( | 27 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( |
23 BluetoothRemoteGattService::GattErrorCode error_code, | 28 device::BluetoothRemoteGattService::GattErrorCode error_code, |
24 UMAGATTOperation operation) { | 29 UMAGATTOperation operation) { |
25 switch (error_code) { | 30 switch (error_code) { |
26 case BluetoothRemoteGattService::GATT_ERROR_UNKNOWN: | 31 case device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN: |
27 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); | 32 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); |
28 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; | 33 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; |
29 case BluetoothRemoteGattService::GATT_ERROR_FAILED: | 34 case device::BluetoothRemoteGattService::GATT_ERROR_FAILED: |
30 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); | 35 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); |
31 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; | 36 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; |
32 case BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS: | 37 case device::BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS: |
33 RecordGATTOperationOutcome(operation, | 38 RecordGATTOperationOutcome(operation, |
34 UMAGATTOperationOutcome::IN_PROGRESS); | 39 UMAGATTOperationOutcome::IN_PROGRESS); |
35 return blink::mojom::WebBluetoothError::GATT_OPERATION_IN_PROGRESS; | 40 return blink::mojom::WebBluetoothError::GATT_OPERATION_IN_PROGRESS; |
36 case BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH: | 41 case device::BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH: |
37 RecordGATTOperationOutcome(operation, | 42 RecordGATTOperationOutcome(operation, |
38 UMAGATTOperationOutcome::INVALID_LENGTH); | 43 UMAGATTOperationOutcome::INVALID_LENGTH); |
39 return blink::mojom::WebBluetoothError::GATT_INVALID_ATTRIBUTE_LENGTH; | 44 return blink::mojom::WebBluetoothError::GATT_INVALID_ATTRIBUTE_LENGTH; |
40 case BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED: | 45 case device::BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED: |
41 RecordGATTOperationOutcome(operation, | 46 RecordGATTOperationOutcome(operation, |
42 UMAGATTOperationOutcome::NOT_PERMITTED); | 47 UMAGATTOperationOutcome::NOT_PERMITTED); |
43 return blink::mojom::WebBluetoothError::GATT_NOT_PERMITTED; | 48 return blink::mojom::WebBluetoothError::GATT_NOT_PERMITTED; |
44 case BluetoothRemoteGattService::GATT_ERROR_NOT_AUTHORIZED: | 49 case device::BluetoothRemoteGattService::GATT_ERROR_NOT_AUTHORIZED: |
45 RecordGATTOperationOutcome(operation, | 50 RecordGATTOperationOutcome(operation, |
46 UMAGATTOperationOutcome::NOT_AUTHORIZED); | 51 UMAGATTOperationOutcome::NOT_AUTHORIZED); |
47 return blink::mojom::WebBluetoothError::GATT_NOT_AUTHORIZED; | 52 return blink::mojom::WebBluetoothError::GATT_NOT_AUTHORIZED; |
48 case BluetoothRemoteGattService::GATT_ERROR_NOT_PAIRED: | 53 case device::BluetoothRemoteGattService::GATT_ERROR_NOT_PAIRED: |
49 RecordGATTOperationOutcome(operation, | 54 RecordGATTOperationOutcome(operation, |
50 UMAGATTOperationOutcome::NOT_PAIRED); | 55 UMAGATTOperationOutcome::NOT_PAIRED); |
51 return blink::mojom::WebBluetoothError::GATT_NOT_PAIRED; | 56 return blink::mojom::WebBluetoothError::GATT_NOT_PAIRED; |
52 case BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED: | 57 case device::BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED: |
53 RecordGATTOperationOutcome(operation, | 58 RecordGATTOperationOutcome(operation, |
54 UMAGATTOperationOutcome::NOT_SUPPORTED); | 59 UMAGATTOperationOutcome::NOT_SUPPORTED); |
55 return blink::mojom::WebBluetoothError::GATT_NOT_SUPPORTED; | 60 return blink::mojom::WebBluetoothError::GATT_NOT_SUPPORTED; |
56 } | 61 } |
57 NOTREACHED(); | 62 NOTREACHED(); |
58 return blink::mojom::WebBluetoothError::GATT_UNTRANSLATED_ERROR_CODE; | 63 return blink::mojom::WebBluetoothError::GATT_UNTRANSLATED_ERROR_CODE; |
59 } | 64 } |
60 | 65 |
| 66 // TODO(ortuno): This should really be a BluetoothDevice method. |
| 67 // Replace when implemented. http://crbug.com/552022 |
| 68 std::vector<device::BluetoothRemoteGattCharacteristic*> |
| 69 GetCharacteristicsByUUID(device::BluetoothRemoteGattService* service, |
| 70 const std::string& characteristic_uuid) { |
| 71 std::vector<device::BluetoothRemoteGattCharacteristic*> characteristics; |
| 72 VLOG(1) << "Looking for characteristic: " << characteristic_uuid; |
| 73 for (device::BluetoothRemoteGattCharacteristic* characteristic : |
| 74 service->GetCharacteristics()) { |
| 75 VLOG(1) << "Characteristic in cache: " |
| 76 << characteristic->GetUUID().canonical_value(); |
| 77 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) { |
| 78 characteristics.push_back(characteristic); |
| 79 } |
| 80 } |
| 81 return characteristics; |
| 82 } |
| 83 |
61 } // namespace | 84 } // namespace |
62 | 85 |
63 using CacheQueryResult = BluetoothDispatcherHost::CacheQueryResult; | |
64 | |
65 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | 86 WebBluetoothServiceImpl::WebBluetoothServiceImpl( |
66 RenderFrameHost* render_frame_host, | 87 RenderFrameHost* render_frame_host, |
67 blink::mojom::WebBluetoothServiceRequest request) | 88 blink::mojom::WebBluetoothServiceRequest request) |
68 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), | 89 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), |
69 render_frame_host_(render_frame_host), | 90 render_frame_host_(render_frame_host), |
70 binding_(this, std::move(request)), | 91 binding_(this, std::move(request)), |
71 weak_ptr_factory_(this) { | 92 weak_ptr_factory_(this) { |
72 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 93 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
73 CHECK(web_contents()); | 94 CHECK(web_contents()); |
74 | 95 |
75 GetBluetoothDispatcherHost()->AddAdapterObserver(this); | 96 GetBluetoothDispatcherHost()->AddAdapterObserver(this); |
76 } | 97 } |
77 | 98 |
78 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() { | 99 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() { |
79 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 100 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
80 GetBluetoothDispatcherHost()->RemoveAdapterObserver(this); | 101 GetBluetoothDispatcherHost()->RemoveAdapterObserver(this); |
81 } | 102 } |
82 | 103 |
83 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler( | 104 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler( |
84 base::Closure closure) { | 105 base::Closure closure) { |
85 binding_.set_connection_error_handler(closure); | 106 binding_.set_connection_error_handler(closure); |
86 } | 107 } |
87 | 108 |
88 void WebBluetoothServiceImpl::DidFinishNavigation( | 109 void WebBluetoothServiceImpl::DidFinishNavigation( |
89 NavigationHandle* navigation_handle) { | 110 NavigationHandle* navigation_handle) { |
90 if (navigation_handle->HasCommitted() && | 111 if (navigation_handle->HasCommitted() && |
91 navigation_handle->GetRenderFrameHost() == render_frame_host_ && | 112 navigation_handle->GetRenderFrameHost() == render_frame_host_ && |
92 !navigation_handle->IsSamePage()) { | 113 !navigation_handle->IsSamePage()) { |
93 // After navigation we need to clear the frame's state. | |
94 ClearState(); | 114 ClearState(); |
95 } | 115 } |
96 } | 116 } |
97 | 117 |
98 void WebBluetoothServiceImpl::AdapterPresentChanged( | 118 void WebBluetoothServiceImpl::AdapterPresentChanged( |
99 device::BluetoothAdapter* adapter, | 119 device::BluetoothAdapter* adapter, |
100 bool present) { | 120 bool present) { |
101 if (!present) { | 121 if (!present) { |
102 ClearState(); | 122 ClearState(); |
103 } | 123 } |
104 } | 124 } |
105 | 125 |
106 void WebBluetoothServiceImpl::GattCharacteristicValueChanged( | 126 void WebBluetoothServiceImpl::GattCharacteristicValueChanged( |
107 device::BluetoothAdapter* adapter, | 127 device::BluetoothAdapter* adapter, |
108 device::BluetoothRemoteGattCharacteristic* characteristic, | 128 device::BluetoothRemoteGattCharacteristic* characteristic, |
109 const std::vector<uint8_t>& value) { | 129 const std::vector<uint8_t>& value) { |
110 // TODO(ortuno): Only send characteristic value changed events for | 130 // Don't notify of characteristics that we haven't returned. |
111 // characteristics that we've returned in the past. We can't yet do | 131 if (!ContainsKey(characteristic_id_to_service_id_, |
112 // this because WebBluetoothServiceImpl doesn't have direct access | 132 characteristic->GetIdentifier())) { |
113 // to the list of returned characteristics. | |
114 // https://crbug.com/508771 | |
115 if (BluetoothBlacklist::Get().IsExcluded(characteristic->GetUUID())) { | |
116 return; | 133 return; |
117 } | 134 } |
118 | 135 |
119 // On Chrome OS and Linux, GattCharacteristicValueChanged is called before the | 136 // On Chrome OS and Linux, GattCharacteristicValueChanged is called before the |
120 // success callback for ReadRemoteCharacteristic is called, which could result | 137 // success callback for ReadRemoteCharacteristic is called, which could result |
121 // in an event being fired before the readValue promise is resolved. | 138 // in an event being fired before the readValue promise is resolved. |
122 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( | 139 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( |
123 FROM_HERE, | 140 FROM_HERE, |
124 base::Bind(&WebBluetoothServiceImpl::NotifyCharacteristicValueChanged, | 141 base::Bind(&WebBluetoothServiceImpl::NotifyCharacteristicValueChanged, |
125 weak_ptr_factory_.GetWeakPtr(), | 142 weak_ptr_factory_.GetWeakPtr(), |
(...skipping 10 matching lines...) Expand all Loading... |
136 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); | 153 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); |
137 } | 154 } |
138 } | 155 } |
139 | 156 |
140 void WebBluetoothServiceImpl::SetClient( | 157 void WebBluetoothServiceImpl::SetClient( |
141 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { | 158 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { |
142 DCHECK(!client_.get()); | 159 DCHECK(!client_.get()); |
143 client_.Bind(std::move(client)); | 160 client_.Bind(std::move(client)); |
144 } | 161 } |
145 | 162 |
| 163 void WebBluetoothServiceImpl::RemoteServiceGetCharacteristics( |
| 164 const mojo::String& service_instance_id, |
| 165 blink::mojom::WebBluetoothGATTQueryQuantity quantity, |
| 166 const mojo::String& characteristics_uuid, |
| 167 const RemoteServiceGetCharacteristicsCallback& callback) { |
| 168 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 169 RecordWebBluetoothFunctionCall( |
| 170 quantity == blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE |
| 171 ? UMAWebBluetoothFunction::SERVICE_GET_CHARACTERISTIC |
| 172 : UMAWebBluetoothFunction::SERVICE_GET_CHARACTERISTICS); |
| 173 RecordGetCharacteristicsCharacteristic(quantity, characteristics_uuid); |
| 174 |
| 175 if (!characteristics_uuid.is_null() && |
| 176 BluetoothBlacklist::Get().IsExcluded( |
| 177 device::BluetoothUUID(characteristics_uuid))) { |
| 178 RecordGetCharacteristicsOutcome(quantity, |
| 179 UMAGetCharacteristicOutcome::BLACKLISTED); |
| 180 callback.Run( |
| 181 blink::mojom::WebBluetoothError::BLACKLISTED_CHARACTERISTIC_UUID, |
| 182 nullptr /* characteristics */); |
| 183 return; |
| 184 } |
| 185 |
| 186 const CacheQueryResult query_result = |
| 187 GetBluetoothDispatcherHost()->QueryCacheForService(GetOrigin(), |
| 188 service_instance_id); |
| 189 |
| 190 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
| 191 binding_.Close(); |
| 192 return; |
| 193 } |
| 194 |
| 195 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
| 196 RecordGetCharacteristicsOutcome(quantity, query_result.outcome); |
| 197 callback.Run(query_result.GetWebError(), nullptr /* characteristics */); |
| 198 return; |
| 199 } |
| 200 |
| 201 std::vector<device::BluetoothRemoteGattCharacteristic*> characteristics = |
| 202 characteristics_uuid.is_null() |
| 203 ? query_result.service->GetCharacteristics() |
| 204 : GetCharacteristicsByUUID(query_result.service, |
| 205 characteristics_uuid); |
| 206 |
| 207 mojo::Array<blink::mojom::WebBluetoothRemoteGATTCharacteristicPtr> |
| 208 response_characteristics; |
| 209 for (device::BluetoothRemoteGattCharacteristic* characteristic : |
| 210 characteristics) { |
| 211 if (BluetoothBlacklist::Get().IsExcluded(characteristic->GetUUID())) { |
| 212 continue; |
| 213 } |
| 214 std::string characteristic_instance_id = characteristic->GetIdentifier(); |
| 215 auto insert_result = characteristic_id_to_service_id_.insert( |
| 216 std::make_pair(characteristic_instance_id, service_instance_id)); |
| 217 // If value is already in map, DCHECK it's valid. |
| 218 if (!insert_result.second) |
| 219 DCHECK(insert_result.first->second == service_instance_id); |
| 220 |
| 221 blink::mojom::WebBluetoothRemoteGATTCharacteristicPtr characteristic_ptr = |
| 222 blink::mojom::WebBluetoothRemoteGATTCharacteristic::New(); |
| 223 characteristic_ptr->instance_id = |
| 224 mojo::String::From(characteristic_instance_id); |
| 225 characteristic_ptr->uuid = |
| 226 mojo::String::From(characteristic->GetUUID().canonical_value()); |
| 227 characteristic_ptr->properties = |
| 228 static_cast<uint32_t>(characteristic->GetProperties()); |
| 229 response_characteristics.push_back(std::move(characteristic_ptr)); |
| 230 |
| 231 if (quantity == blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE) { |
| 232 break; |
| 233 } |
| 234 } |
| 235 |
| 236 if (!response_characteristics.empty()) { |
| 237 RecordGetCharacteristicsOutcome(quantity, |
| 238 UMAGetCharacteristicOutcome::SUCCESS); |
| 239 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, |
| 240 std::move(response_characteristics)); |
| 241 return; |
| 242 } |
| 243 RecordGetCharacteristicsOutcome( |
| 244 quantity, characteristics_uuid.is_null() |
| 245 ? UMAGetCharacteristicOutcome::NO_CHARACTERISTICS |
| 246 : UMAGetCharacteristicOutcome::NOT_FOUND); |
| 247 callback.Run(characteristics_uuid.is_null() |
| 248 ? blink::mojom::WebBluetoothError::NO_CHARACTERISTICS_FOUND |
| 249 : blink::mojom::WebBluetoothError::CHARACTERISTIC_NOT_FOUND, |
| 250 nullptr /* characteristics */); |
| 251 return; |
| 252 } |
| 253 |
146 void WebBluetoothServiceImpl::RemoteCharacteristicReadValue( | 254 void WebBluetoothServiceImpl::RemoteCharacteristicReadValue( |
147 const mojo::String& characteristic_instance_id, | 255 const mojo::String& characteristic_instance_id, |
148 const RemoteCharacteristicReadValueCallback& callback) { | 256 const RemoteCharacteristicReadValueCallback& callback) { |
149 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 257 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
150 RecordWebBluetoothFunctionCall( | 258 RecordWebBluetoothFunctionCall( |
151 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | 259 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); |
152 | 260 |
153 const CacheQueryResult query_result = | 261 const CacheQueryResult query_result = |
154 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 262 QueryCacheForCharacteristic(characteristic_instance_id); |
155 GetOrigin(), characteristic_instance_id); | |
156 | 263 |
157 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 264 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
158 return; | 265 return; |
159 } | 266 } |
160 | 267 |
161 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 268 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
162 RecordCharacteristicReadValueOutcome(query_result.outcome); | 269 RecordCharacteristicReadValueOutcome(query_result.outcome); |
163 callback.Run(query_result.GetWebError(), nullptr /* value */); | 270 callback.Run(query_result.GetWebError(), nullptr /* value */); |
164 return; | 271 return; |
165 } | 272 } |
(...skipping 23 matching lines...) Expand all Loading... |
189 | 296 |
190 // We perform the length check on the renderer side. So if we | 297 // We perform the length check on the renderer side. So if we |
191 // get a value with length > 512, we can assume it's a hostile | 298 // get a value with length > 512, we can assume it's a hostile |
192 // renderer and kill it. | 299 // renderer and kill it. |
193 if (value.size() > 512) { | 300 if (value.size() > 512) { |
194 CrashRendererAndClosePipe(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 301 CrashRendererAndClosePipe(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
195 return; | 302 return; |
196 } | 303 } |
197 | 304 |
198 const CacheQueryResult query_result = | 305 const CacheQueryResult query_result = |
199 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 306 QueryCacheForCharacteristic(characteristic_instance_id); |
200 GetOrigin(), characteristic_instance_id); | |
201 | 307 |
202 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 308 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
203 binding_.Close(); | |
204 return; | 309 return; |
205 } | 310 } |
206 | 311 |
207 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 312 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
208 RecordCharacteristicWriteValueOutcome(query_result.outcome); | 313 RecordCharacteristicWriteValueOutcome(query_result.outcome); |
209 callback.Run(query_result.GetWebError()); | 314 callback.Run(query_result.GetWebError()); |
210 return; | 315 return; |
211 } | 316 } |
212 | 317 |
213 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | 318 if (BluetoothBlacklist::Get().IsExcludedFromWrites( |
(...skipping 22 matching lines...) Expand all Loading... |
236 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 341 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
237 if (iter != characteristic_id_to_notify_session_.end() && | 342 if (iter != characteristic_id_to_notify_session_.end() && |
238 iter->second->IsActive()) { | 343 iter->second->IsActive()) { |
239 // If the frame has already started notifications and the notifications | 344 // If the frame has already started notifications and the notifications |
240 // are active we return SUCCESS. | 345 // are active we return SUCCESS. |
241 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | 346 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); |
242 return; | 347 return; |
243 } | 348 } |
244 | 349 |
245 const CacheQueryResult query_result = | 350 const CacheQueryResult query_result = |
246 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 351 QueryCacheForCharacteristic(characteristic_instance_id); |
247 GetOrigin(), characteristic_instance_id); | |
248 | 352 |
249 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 353 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
250 binding_.Close(); | |
251 return; | 354 return; |
252 } | 355 } |
253 | 356 |
254 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 357 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
255 RecordStartNotificationsOutcome(query_result.outcome); | 358 RecordStartNotificationsOutcome(query_result.outcome); |
256 callback.Run(query_result.GetWebError()); | 359 callback.Run(query_result.GetWebError()); |
257 return; | 360 return; |
258 } | 361 } |
259 | 362 |
260 device::BluetoothRemoteGattCharacteristic::Properties notify_or_indicate = | 363 device::BluetoothRemoteGattCharacteristic::Properties notify_or_indicate = |
(...skipping 13 matching lines...) Expand all Loading... |
274 } | 377 } |
275 | 378 |
276 void WebBluetoothServiceImpl::RemoteCharacteristicStopNotifications( | 379 void WebBluetoothServiceImpl::RemoteCharacteristicStopNotifications( |
277 const mojo::String& characteristic_instance_id, | 380 const mojo::String& characteristic_instance_id, |
278 const RemoteCharacteristicStopNotificationsCallback& callback) { | 381 const RemoteCharacteristicStopNotificationsCallback& callback) { |
279 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 382 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
280 RecordWebBluetoothFunctionCall( | 383 RecordWebBluetoothFunctionCall( |
281 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); | 384 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
282 | 385 |
283 const CacheQueryResult query_result = | 386 const CacheQueryResult query_result = |
284 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 387 QueryCacheForCharacteristic(characteristic_instance_id); |
285 GetOrigin(), characteristic_instance_id); | |
286 | 388 |
287 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 389 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
288 binding_.Close(); | |
289 return; | 390 return; |
290 } | 391 } |
291 | 392 |
292 auto notify_session_iter = | 393 auto notify_session_iter = |
293 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 394 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
294 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { | 395 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
295 // If the frame hasn't subscribed to notifications before we just | 396 // If the frame hasn't subscribed to notifications before we just |
296 // run the callback. | 397 // run the callback. |
297 callback.Run(); | 398 callback.Run(); |
298 return; | 399 return; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 error_code, UMAGATTOperation::START_NOTIFICATIONS)); | 458 error_code, UMAGATTOperation::START_NOTIFICATIONS)); |
358 } | 459 } |
359 | 460 |
360 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 461 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( |
361 const std::string& characteristic_instance_id, | 462 const std::string& characteristic_instance_id, |
362 const RemoteCharacteristicStopNotificationsCallback& callback) { | 463 const RemoteCharacteristicStopNotificationsCallback& callback) { |
363 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 464 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
364 callback.Run(); | 465 callback.Run(); |
365 } | 466 } |
366 | 467 |
| 468 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( |
| 469 const std::string& characteristic_instance_id) { |
| 470 auto characteristic_iter = |
| 471 characteristic_id_to_service_id_.find(characteristic_instance_id); |
| 472 |
| 473 // Kill the render, see "ID Not in Map Note" above. |
| 474 if (characteristic_iter == characteristic_id_to_service_id_.end()) { |
| 475 CrashRendererAndClosePipe(bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
| 476 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 477 } |
| 478 |
| 479 CacheQueryResult result = GetBluetoothDispatcherHost()->QueryCacheForService( |
| 480 GetOrigin(), characteristic_iter->second); |
| 481 |
| 482 // TODO(ortuno): Remove once QueryCacheForService closes binding_. |
| 483 // http://crbug.com/508771 |
| 484 if (result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
| 485 binding_.Close(); |
| 486 } |
| 487 |
| 488 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
| 489 return result; |
| 490 } |
| 491 |
| 492 result.characteristic = |
| 493 result.service->GetCharacteristic(characteristic_instance_id); |
| 494 |
| 495 if (result.characteristic == nullptr) { |
| 496 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
| 497 } |
| 498 |
| 499 return result; |
| 500 } |
| 501 |
367 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 502 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { |
368 return render_frame_host_->GetProcess(); | 503 return render_frame_host_->GetProcess(); |
369 } | 504 } |
370 | 505 |
371 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { | 506 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { |
372 RenderProcessHostImpl* render_process_host_impl = | 507 RenderProcessHostImpl* render_process_host_impl = |
373 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); | 508 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); |
374 return render_process_host_impl->GetBluetoothDispatcherHost(); | 509 return render_process_host_impl->GetBluetoothDispatcherHost(); |
375 } | 510 } |
376 | 511 |
377 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 512 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( |
378 bad_message::BadMessageReason reason) { | 513 bad_message::BadMessageReason reason) { |
379 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); | 514 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); |
380 binding_.Close(); | 515 binding_.Close(); |
381 } | 516 } |
382 | 517 |
383 url::Origin WebBluetoothServiceImpl::GetOrigin() { | 518 url::Origin WebBluetoothServiceImpl::GetOrigin() { |
384 return render_frame_host_->GetLastCommittedOrigin(); | 519 return render_frame_host_->GetLastCommittedOrigin(); |
385 } | 520 } |
386 | 521 |
387 void WebBluetoothServiceImpl::ClearState() { | 522 void WebBluetoothServiceImpl::ClearState() { |
388 characteristic_id_to_notify_session_.clear(); | 523 characteristic_id_to_notify_session_.clear(); |
| 524 characteristic_id_to_service_id_.clear(); |
389 } | 525 } |
390 | 526 |
391 } // namespace content | 527 } // namespace content |
OLD | NEW |