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_, characteristic_to_service_, |
| 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer |
| 9 // obtains the corresponding ID from this class and it will be added to the map |
| 10 // 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_to_service_, |
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::WebBluetoothQueryType type, |
| 166 const mojo::String& characteristics_uuid, |
| 167 const RemoteServiceGetCharacteristicsCallback& callback) { |
| 168 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 169 RecordWebBluetoothFunctionCall( |
| 170 type == blink::mojom::WebBluetoothQueryType::SINGLE |
| 171 ? UMAWebBluetoothFunction::SERVICE_GET_CHARACTERISTIC |
| 172 : UMAWebBluetoothFunction::SERVICE_GET_CHARACTERISTICS); |
| 173 RecordGetCharacteristicsCharacteristic(type, characteristics_uuid); |
| 174 |
| 175 if (!characteristics_uuid.is_null() && |
| 176 BluetoothBlacklist::Get().IsExcluded( |
| 177 device::BluetoothUUID(characteristics_uuid))) { |
| 178 RecordGetCharacteristicsOutcome(type, |
| 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(type, 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_to_service_.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 characteristics_uuid.is_null() |
| 227 ? mojo::String::From(characteristic->GetUUID().canonical_value()) |
| 228 : nullptr; |
| 229 characteristic_ptr->properties = |
| 230 static_cast<uint32_t>(characteristic->GetProperties()); |
| 231 response_characteristics.push_back(std::move(characteristic_ptr)); |
| 232 |
| 233 if (type == blink::mojom::WebBluetoothQueryType::SINGLE) { |
| 234 break; |
| 235 } |
| 236 } |
| 237 |
| 238 if (!response_characteristics.empty()) { |
| 239 RecordGetCharacteristicsOutcome(type, UMAGetCharacteristicOutcome::SUCCESS); |
| 240 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, |
| 241 std::move(response_characteristics)); |
| 242 return; |
| 243 } |
| 244 RecordGetCharacteristicsOutcome( |
| 245 type, characteristics_uuid.is_null() |
| 246 ? UMAGetCharacteristicOutcome::NO_CHARACTERISTICS |
| 247 : UMAGetCharacteristicOutcome::NOT_FOUND); |
| 248 callback.Run(characteristics_uuid.is_null() |
| 249 ? blink::mojom::WebBluetoothError::NO_CHARACTERISTICS_FOUND |
| 250 : blink::mojom::WebBluetoothError::CHARACTERISTIC_NOT_FOUND, |
| 251 nullptr /* characteristics */); |
| 252 return; |
| 253 } |
| 254 |
146 void WebBluetoothServiceImpl::RemoteCharacteristicReadValue( | 255 void WebBluetoothServiceImpl::RemoteCharacteristicReadValue( |
147 const mojo::String& characteristic_instance_id, | 256 const mojo::String& characteristic_instance_id, |
148 const RemoteCharacteristicReadValueCallback& callback) { | 257 const RemoteCharacteristicReadValueCallback& callback) { |
149 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 258 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
150 RecordWebBluetoothFunctionCall( | 259 RecordWebBluetoothFunctionCall( |
151 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | 260 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); |
152 | 261 |
153 const CacheQueryResult query_result = | 262 const CacheQueryResult query_result = |
154 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 263 QueryCacheForCharacteristic(characteristic_instance_id); |
155 GetOrigin(), characteristic_instance_id); | |
156 | 264 |
157 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 265 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
158 return; | 266 return; |
159 } | 267 } |
160 | 268 |
161 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 269 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
162 RecordCharacteristicReadValueOutcome(query_result.outcome); | 270 RecordCharacteristicReadValueOutcome(query_result.outcome); |
163 callback.Run(query_result.GetWebError(), nullptr /* value */); | 271 callback.Run(query_result.GetWebError(), nullptr /* value */); |
164 return; | 272 return; |
165 } | 273 } |
(...skipping 23 matching lines...) Expand all Loading... |
189 | 297 |
190 // We perform the length check on the renderer side. So if we | 298 // 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 | 299 // get a value with length > 512, we can assume it's a hostile |
192 // renderer and kill it. | 300 // renderer and kill it. |
193 if (value.size() > 512) { | 301 if (value.size() > 512) { |
194 CrashRendererAndClosePipe(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 302 CrashRendererAndClosePipe(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
195 return; | 303 return; |
196 } | 304 } |
197 | 305 |
198 const CacheQueryResult query_result = | 306 const CacheQueryResult query_result = |
199 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 307 QueryCacheForCharacteristic(characteristic_instance_id); |
200 GetOrigin(), characteristic_instance_id); | |
201 | 308 |
202 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 309 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
203 binding_.Close(); | |
204 return; | 310 return; |
205 } | 311 } |
206 | 312 |
207 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 313 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
208 RecordCharacteristicWriteValueOutcome(query_result.outcome); | 314 RecordCharacteristicWriteValueOutcome(query_result.outcome); |
209 callback.Run(query_result.GetWebError()); | 315 callback.Run(query_result.GetWebError()); |
210 return; | 316 return; |
211 } | 317 } |
212 | 318 |
213 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | 319 if (BluetoothBlacklist::Get().IsExcludedFromWrites( |
(...skipping 22 matching lines...) Expand all Loading... |
236 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 342 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
237 if (iter != characteristic_id_to_notify_session_.end() && | 343 if (iter != characteristic_id_to_notify_session_.end() && |
238 iter->second->IsActive()) { | 344 iter->second->IsActive()) { |
239 // If the frame has already started notifications and the notifications | 345 // If the frame has already started notifications and the notifications |
240 // are active we return SUCCESS. | 346 // are active we return SUCCESS. |
241 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | 347 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); |
242 return; | 348 return; |
243 } | 349 } |
244 | 350 |
245 const CacheQueryResult query_result = | 351 const CacheQueryResult query_result = |
246 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 352 QueryCacheForCharacteristic(characteristic_instance_id); |
247 GetOrigin(), characteristic_instance_id); | |
248 | 353 |
249 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 354 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
250 binding_.Close(); | |
251 return; | 355 return; |
252 } | 356 } |
253 | 357 |
254 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 358 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
255 RecordStartNotificationsOutcome(query_result.outcome); | 359 RecordStartNotificationsOutcome(query_result.outcome); |
256 callback.Run(query_result.GetWebError()); | 360 callback.Run(query_result.GetWebError()); |
257 return; | 361 return; |
258 } | 362 } |
259 | 363 |
260 device::BluetoothRemoteGattCharacteristic::Properties notify_or_indicate = | 364 device::BluetoothRemoteGattCharacteristic::Properties notify_or_indicate = |
(...skipping 13 matching lines...) Expand all Loading... |
274 } | 378 } |
275 | 379 |
276 void WebBluetoothServiceImpl::RemoteCharacteristicStopNotifications( | 380 void WebBluetoothServiceImpl::RemoteCharacteristicStopNotifications( |
277 const mojo::String& characteristic_instance_id, | 381 const mojo::String& characteristic_instance_id, |
278 const RemoteCharacteristicStopNotificationsCallback& callback) { | 382 const RemoteCharacteristicStopNotificationsCallback& callback) { |
279 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 383 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
280 RecordWebBluetoothFunctionCall( | 384 RecordWebBluetoothFunctionCall( |
281 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); | 385 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
282 | 386 |
283 const CacheQueryResult query_result = | 387 const CacheQueryResult query_result = |
284 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | 388 QueryCacheForCharacteristic(characteristic_instance_id); |
285 GetOrigin(), characteristic_instance_id); | |
286 | 389 |
287 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 390 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
288 binding_.Close(); | |
289 return; | 391 return; |
290 } | 392 } |
291 | 393 |
292 auto notify_session_iter = | 394 auto notify_session_iter = |
293 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 395 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
294 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { | 396 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
295 // If the frame hasn't subscribed to notifications before we just | 397 // If the frame hasn't subscribed to notifications before we just |
296 // run the callback. | 398 // run the callback. |
297 callback.Run(); | 399 callback.Run(); |
298 return; | 400 return; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 error_code, UMAGATTOperation::START_NOTIFICATIONS)); | 459 error_code, UMAGATTOperation::START_NOTIFICATIONS)); |
358 } | 460 } |
359 | 461 |
360 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 462 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( |
361 const std::string& characteristic_instance_id, | 463 const std::string& characteristic_instance_id, |
362 const RemoteCharacteristicStopNotificationsCallback& callback) { | 464 const RemoteCharacteristicStopNotificationsCallback& callback) { |
363 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 465 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
364 callback.Run(); | 466 callback.Run(); |
365 } | 467 } |
366 | 468 |
| 469 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( |
| 470 const std::string& characteristic_instance_id) { |
| 471 auto characteristic_iter = |
| 472 characteristic_to_service_.find(characteristic_instance_id); |
| 473 |
| 474 // Kill the render, see "ID Not in Map Note" above. |
| 475 if (characteristic_iter == characteristic_to_service_.end()) { |
| 476 CrashRendererAndClosePipe(bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
| 477 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 478 } |
| 479 |
| 480 CacheQueryResult result = GetBluetoothDispatcherHost()->QueryCacheForService( |
| 481 GetOrigin(), characteristic_iter->second); |
| 482 |
| 483 // TODO(ortuno): Remove once QueryCacheForService closes binding_. |
| 484 // http://crbug.com/508771 |
| 485 if (result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
| 486 binding_.Close(); |
| 487 } |
| 488 |
| 489 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
| 490 return result; |
| 491 } |
| 492 |
| 493 result.characteristic = |
| 494 result.service->GetCharacteristic(characteristic_instance_id); |
| 495 |
| 496 if (result.characteristic == nullptr) { |
| 497 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
| 498 } |
| 499 |
| 500 return result; |
| 501 } |
| 502 |
367 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 503 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { |
368 return render_frame_host_->GetProcess(); | 504 return render_frame_host_->GetProcess(); |
369 } | 505 } |
370 | 506 |
371 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { | 507 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { |
372 RenderProcessHostImpl* render_process_host_impl = | 508 RenderProcessHostImpl* render_process_host_impl = |
373 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); | 509 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); |
374 return render_process_host_impl->GetBluetoothDispatcherHost(); | 510 return render_process_host_impl->GetBluetoothDispatcherHost(); |
375 } | 511 } |
376 | 512 |
377 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 513 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( |
378 bad_message::BadMessageReason reason) { | 514 bad_message::BadMessageReason reason) { |
379 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); | 515 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); |
380 binding_.Close(); | 516 binding_.Close(); |
381 } | 517 } |
382 | 518 |
383 url::Origin WebBluetoothServiceImpl::GetOrigin() { | 519 url::Origin WebBluetoothServiceImpl::GetOrigin() { |
384 return render_frame_host_->GetLastCommittedOrigin(); | 520 return render_frame_host_->GetLastCommittedOrigin(); |
385 } | 521 } |
386 | 522 |
387 void WebBluetoothServiceImpl::ClearState() { | 523 void WebBluetoothServiceImpl::ClearState() { |
388 characteristic_id_to_notify_session_.clear(); | 524 characteristic_id_to_notify_session_.clear(); |
| 525 characteristic_to_service_.clear(); |
389 } | 526 } |
390 | 527 |
391 } // namespace content | 528 } // namespace content |
OLD | NEW |