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 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 }; | 43 }; |
44 | 44 |
45 enum class UMARequestDeviceOutcome { | 45 enum class UMARequestDeviceOutcome { |
46 SUCCESS = 0, | 46 SUCCESS = 0, |
47 NO_BLUETOOTH_ADAPTER = 1, | 47 NO_BLUETOOTH_ADAPTER = 1, |
48 NO_RENDER_FRAME = 2, | 48 NO_RENDER_FRAME = 2, |
49 DISCOVERY_START_FAILED = 3, | 49 DISCOVERY_START_FAILED = 3, |
50 DISCOVERY_STOP_FAILED = 4, | 50 DISCOVERY_STOP_FAILED = 4, |
51 NO_MATCHING_DEVICES_FOUND = 5, | 51 NO_MATCHING_DEVICES_FOUND = 5, |
52 // NOTE: Add new requestDevice() outcomes immediately above this line. Make | 52 // NOTE: Add new requestDevice() outcomes immediately above this line. Make |
53 // sure to update the enum list in tools/histogram/histograms.xml accordingly. | 53 // sure to update the enum list in |
54 // tools/metrics/histogram/histograms.xml accordingly. | |
54 COUNT | 55 COUNT |
55 }; | 56 }; |
56 | 57 |
57 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { | 58 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { |
58 UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", | 59 UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", |
59 static_cast<int>(outcome), | 60 static_cast<int>(outcome), |
60 static_cast<int>(UMARequestDeviceOutcome::COUNT)); | 61 static_cast<int>(UMARequestDeviceOutcome::COUNT)); |
61 } | 62 } |
62 | 63 |
64 enum class UMAWebBluetoothFunction { | |
65 REQUEST_DEVICE, | |
66 CONNECT_GATT, | |
67 GET_PRIMARY_SERVICE, | |
68 GET_CHARACTERISTIC, | |
69 CHARACTERISTIC_READ_VALUE, | |
70 CHARACTERISTIC_WRITE_VALUE, | |
71 // NOTE: Add new actions immediately above this line. Make sure to update the | |
72 // enum list in tools/metrics/histogram/histograms.xml accordingly. | |
73 COUNT | |
74 }; | |
75 | |
76 void RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction function) { | |
77 UMA_HISTOGRAM_ENUMERATION("Bluetooth.Web.FunctionCall.Count", | |
scheib
2015/08/04 18:30:22
Bluetooth.Web.* LGTM ... we'll rename the others i
ortuno
2015/08/04 18:32:24
Yup. There is only one more which is in RequestDev
| |
78 static_cast<int>(function), | |
79 static_cast<int>(UMAWebBluetoothFunction::COUNT)); | |
80 } | |
81 | |
63 // TODO(ortuno): Once we have a chooser for scanning and the right | 82 // TODO(ortuno): Once we have a chooser for scanning and the right |
64 // callback for discovered services we should delete these constants. | 83 // callback for discovered services we should delete these constants. |
65 // https://crbug.com/436280 and https://crbug.com/484504 | 84 // https://crbug.com/436280 and https://crbug.com/484504 |
66 const int kDelayTime = 5; // 5 seconds for scanning and discovering | 85 const int kDelayTime = 5; // 5 seconds for scanning and discovering |
67 const int kTestingDelayTime = 0; // No need to wait during tests | 86 const int kTestingDelayTime = 0; // No need to wait during tests |
68 | 87 |
69 // Defined at | 88 // Defined at |
70 // https://webbluetoothchrome.github.io/web-bluetooth/#dfn-matches-a-filter | 89 // https://webbluetoothchrome.github.io/web-bluetooth/#dfn-matches-a-filter |
71 bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids, | 90 bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids, |
72 const content::BluetoothScanFilter& filter) { | 91 const content::BluetoothScanFilter& filter) { |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 return discovery_filter.Pass(); | 261 return discovery_filter.Pass(); |
243 } | 262 } |
244 | 263 |
245 void BluetoothDispatcherHost::OnRequestDevice( | 264 void BluetoothDispatcherHost::OnRequestDevice( |
246 int thread_id, | 265 int thread_id, |
247 int request_id, | 266 int request_id, |
248 int frame_routing_id, | 267 int frame_routing_id, |
249 const std::vector<BluetoothScanFilter>& filters, | 268 const std::vector<BluetoothScanFilter>& filters, |
250 const std::vector<BluetoothUUID>& optional_services) { | 269 const std::vector<BluetoothUUID>& optional_services) { |
251 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 270 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
271 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); | |
252 | 272 |
253 RenderFrameHostImpl* render_frame_host = | 273 RenderFrameHostImpl* render_frame_host = |
254 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); | 274 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); |
255 | 275 |
256 if (!render_frame_host) { | 276 if (!render_frame_host) { |
257 DLOG(WARNING) | 277 DLOG(WARNING) |
258 << "Got a requestDevice IPC without a matching RenderFrameHost: " | 278 << "Got a requestDevice IPC without a matching RenderFrameHost: " |
259 << render_process_id_ << ", " << frame_routing_id; | 279 << render_process_id_ << ", " << frame_routing_id; |
260 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_RENDER_FRAME); | 280 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_RENDER_FRAME); |
261 Send(new BluetoothMsg_RequestDeviceError( | 281 Send(new BluetoothMsg_RequestDeviceError( |
(...skipping 27 matching lines...) Expand all Loading... | |
289 thread_id, request_id, WebBluetoothError::NoBluetoothAdapter)); | 309 thread_id, request_id, WebBluetoothError::NoBluetoothAdapter)); |
290 } | 310 } |
291 return; | 311 return; |
292 } | 312 } |
293 | 313 |
294 void BluetoothDispatcherHost::OnConnectGATT( | 314 void BluetoothDispatcherHost::OnConnectGATT( |
295 int thread_id, | 315 int thread_id, |
296 int request_id, | 316 int request_id, |
297 const std::string& device_instance_id) { | 317 const std::string& device_instance_id) { |
298 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 318 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
319 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | |
320 | |
299 // TODO(ortuno): Right now it's pointless to check if the domain has access to | 321 // TODO(ortuno): Right now it's pointless to check if the domain has access to |
300 // the device, because any domain can connect to any device. But once | 322 // the device, because any domain can connect to any device. But once |
301 // permissions are implemented we should check that the domain has access to | 323 // permissions are implemented we should check that the domain has access to |
302 // the device. https://crbug.com/484745 | 324 // the device. https://crbug.com/484745 |
303 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); | 325 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); |
304 if (device == nullptr) { // See "NETWORK_ERROR Note" above. | 326 if (device == nullptr) { // See "NETWORK_ERROR Note" above. |
305 Send(new BluetoothMsg_ConnectGATTError( | 327 Send(new BluetoothMsg_ConnectGATTError( |
306 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); | 328 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); |
307 return; | 329 return; |
308 } | 330 } |
309 device->CreateGattConnection( | 331 device->CreateGattConnection( |
310 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, | 332 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, |
311 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 333 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
312 device_instance_id), | 334 device_instance_id), |
313 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, | 335 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, |
314 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 336 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
315 device_instance_id)); | 337 device_instance_id)); |
316 } | 338 } |
317 | 339 |
318 void BluetoothDispatcherHost::OnGetPrimaryService( | 340 void BluetoothDispatcherHost::OnGetPrimaryService( |
319 int thread_id, | 341 int thread_id, |
320 int request_id, | 342 int request_id, |
321 const std::string& device_instance_id, | 343 const std::string& device_instance_id, |
322 const std::string& service_uuid) { | 344 const std::string& service_uuid) { |
323 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 345 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
346 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | |
347 | |
324 // TODO(ortuno): Check if device_instance_id is in "allowed devices" | 348 // TODO(ortuno): Check if device_instance_id is in "allowed devices" |
325 // https://crbug.com/493459 | 349 // https://crbug.com/493459 |
326 // TODO(ortuno): Check if service_uuid is in "allowed services" | 350 // TODO(ortuno): Check if service_uuid is in "allowed services" |
327 // https://crbug.com/493460 | 351 // https://crbug.com/493460 |
328 // For now just wait a fixed time and call OnServiceDiscovered. | 352 // For now just wait a fixed time and call OnServiceDiscovered. |
329 // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504 | 353 // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504 |
330 BrowserThread::PostDelayedTask( | 354 BrowserThread::PostDelayedTask( |
331 BrowserThread::UI, FROM_HERE, | 355 BrowserThread::UI, FROM_HERE, |
332 base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered, | 356 base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered, |
333 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 357 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
334 device_instance_id, service_uuid), | 358 device_instance_id, service_uuid), |
335 base::TimeDelta::FromSeconds(current_delay_time_)); | 359 base::TimeDelta::FromSeconds(current_delay_time_)); |
336 } | 360 } |
337 | 361 |
338 void BluetoothDispatcherHost::OnGetCharacteristic( | 362 void BluetoothDispatcherHost::OnGetCharacteristic( |
339 int thread_id, | 363 int thread_id, |
340 int request_id, | 364 int request_id, |
341 const std::string& service_instance_id, | 365 const std::string& service_instance_id, |
342 const std::string& characteristic_uuid) { | 366 const std::string& characteristic_uuid) { |
343 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 367 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
368 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); | |
344 | 369 |
345 auto device_iter = service_to_device_.find(service_instance_id); | 370 auto device_iter = service_to_device_.find(service_instance_id); |
346 // A service_instance_id not in the map implies a hostile renderer | 371 // A service_instance_id not in the map implies a hostile renderer |
347 // because a renderer obtains the service id from this class and | 372 // because a renderer obtains the service id from this class and |
348 // it will be added to the map at that time. | 373 // it will be added to the map at that time. |
349 if (device_iter == service_to_device_.end()) { | 374 if (device_iter == service_to_device_.end()) { |
350 // Kill the renderer | 375 // Kill the renderer |
351 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); | 376 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); |
352 return; | 377 return; |
353 } | 378 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 } | 420 } |
396 Send(new BluetoothMsg_GetCharacteristicError( | 421 Send(new BluetoothMsg_GetCharacteristicError( |
397 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); | 422 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); |
398 } | 423 } |
399 | 424 |
400 void BluetoothDispatcherHost::OnReadValue( | 425 void BluetoothDispatcherHost::OnReadValue( |
401 int thread_id, | 426 int thread_id, |
402 int request_id, | 427 int request_id, |
403 const std::string& characteristic_instance_id) { | 428 const std::string& characteristic_instance_id) { |
404 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 429 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
430 RecordWebBluetoothFunctionCall( | |
431 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | |
405 | 432 |
406 auto characteristic_iter = | 433 auto characteristic_iter = |
407 characteristic_to_service_.find(characteristic_instance_id); | 434 characteristic_to_service_.find(characteristic_instance_id); |
408 // A characteristic_instance_id not in the map implies a hostile renderer | 435 // A characteristic_instance_id not in the map implies a hostile renderer |
409 // because a renderer obtains the characteristic id from this class and | 436 // because a renderer obtains the characteristic id from this class and |
410 // it will be added to the map at that time. | 437 // it will be added to the map at that time. |
411 if (characteristic_iter == characteristic_to_service_.end()) { | 438 if (characteristic_iter == characteristic_to_service_.end()) { |
412 // Kill the renderer | 439 // Kill the renderer |
413 bad_message::ReceivedBadMessage(this, | 440 bad_message::ReceivedBadMessage(this, |
414 bad_message::BDH_INVALID_CHARACTERISTIC_ID); | 441 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 477 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
451 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 478 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
452 } | 479 } |
453 | 480 |
454 void BluetoothDispatcherHost::OnWriteValue( | 481 void BluetoothDispatcherHost::OnWriteValue( |
455 int thread_id, | 482 int thread_id, |
456 int request_id, | 483 int request_id, |
457 const std::string& characteristic_instance_id, | 484 const std::string& characteristic_instance_id, |
458 const std::vector<uint8_t>& value) { | 485 const std::vector<uint8_t>& value) { |
459 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 486 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
487 RecordWebBluetoothFunctionCall( | |
488 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
460 | 489 |
461 // Length check per step 3 of writeValue algorithm: | 490 // Length check per step 3 of writeValue algorithm: |
462 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | 491 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue |
463 // We perform the length check on the renderer side. So if we | 492 // We perform the length check on the renderer side. So if we |
464 // get a value with length > 512, we can assume it's a hostile | 493 // get a value with length > 512, we can assume it's a hostile |
465 // renderer and kill it. | 494 // renderer and kill it. |
466 if (value.size() > 512) { | 495 if (value.size() > 512) { |
467 bad_message::ReceivedBadMessage( | 496 bad_message::ReceivedBadMessage( |
468 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 497 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
469 return; | 498 return; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 | 703 |
675 void BluetoothDispatcherHost::OnWriteValueFailed( | 704 void BluetoothDispatcherHost::OnWriteValueFailed( |
676 int thread_id, | 705 int thread_id, |
677 int request_id, | 706 int request_id, |
678 device::BluetoothGattService::GattErrorCode error_code) { | 707 device::BluetoothGattService::GattErrorCode error_code) { |
679 Send(new BluetoothMsg_WriteCharacteristicValueError( | 708 Send(new BluetoothMsg_WriteCharacteristicValueError( |
680 thread_id, request_id, TranslateGATTError(error_code))); | 709 thread_id, request_id, TranslateGATTError(error_code))); |
681 } | 710 } |
682 | 711 |
683 } // namespace content | 712 } // namespace content |
OLD | NEW |