Chromium Code Reviews| 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 |
| 58 enum class UMAWebBluetoothFunction { | |
|
Jeffrey Yasskin
2015/08/03 21:51:13
Maybe put these right next to the function that us
ortuno
2015/08/03 22:41:16
Done.
| |
| 59 REQUEST_DEVICE, | |
| 60 CONNECT_GATT, | |
| 61 GET_PRIMARY_SERVICE, | |
| 62 GET_CHARACTERISTIC, | |
| 63 READ_VALUE, | |
|
Jeffrey Yasskin
2015/08/03 21:51:13
Similarly, mark that these are the characteristic
ortuno
2015/08/03 22:41:16
Done.
| |
| 64 WRITE_VALUE, | |
| 65 // NOTE: Add new actions immediately above this line. Make sure to update the | |
| 66 // enum list in tools/metrics/histogram/histograms.xml accordingly. | |
| 67 COUNT | |
| 68 }; | |
| 69 | |
| 57 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { | 70 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { |
| 58 UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", | 71 UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", |
| 59 static_cast<int>(outcome), | 72 static_cast<int>(outcome), |
| 60 static_cast<int>(UMARequestDeviceOutcome::COUNT)); | 73 static_cast<int>(UMARequestDeviceOutcome::COUNT)); |
| 61 } | 74 } |
| 62 | 75 |
| 76 void RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction function) { | |
| 77 UMA_HISTOGRAM_ENUMERATION("WebBluetooth.FunctionCall.Count", | |
| 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(UMAWebBluetoothFunction::READ_VALUE); | |
| 405 | 431 |
| 406 auto characteristic_iter = | 432 auto characteristic_iter = |
| 407 characteristic_to_service_.find(characteristic_instance_id); | 433 characteristic_to_service_.find(characteristic_instance_id); |
| 408 // A characteristic_instance_id not in the map implies a hostile renderer | 434 // A characteristic_instance_id not in the map implies a hostile renderer |
| 409 // because a renderer obtains the characteristic id from this class and | 435 // because a renderer obtains the characteristic id from this class and |
| 410 // it will be added to the map at that time. | 436 // it will be added to the map at that time. |
| 411 if (characteristic_iter == characteristic_to_service_.end()) { | 437 if (characteristic_iter == characteristic_to_service_.end()) { |
| 412 // Kill the renderer | 438 // Kill the renderer |
| 413 bad_message::ReceivedBadMessage(this, | 439 bad_message::ReceivedBadMessage(this, |
| 414 bad_message::BDH_INVALID_CHARACTERISTIC_ID); | 440 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 476 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
| 451 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 477 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
| 452 } | 478 } |
| 453 | 479 |
| 454 void BluetoothDispatcherHost::OnWriteValue( | 480 void BluetoothDispatcherHost::OnWriteValue( |
| 455 int thread_id, | 481 int thread_id, |
| 456 int request_id, | 482 int request_id, |
| 457 const std::string& characteristic_instance_id, | 483 const std::string& characteristic_instance_id, |
| 458 const std::vector<uint8_t>& value) { | 484 const std::vector<uint8_t>& value) { |
| 459 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 485 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 486 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::WRITE_VALUE); | |
| 460 | 487 |
| 461 // Length check per step 3 of writeValue algorithm: | 488 // Length check per step 3 of writeValue algorithm: |
| 462 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | 489 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue |
| 463 // We perform the length check on the renderer side. So if we | 490 // 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 | 491 // get a value with length > 512, we can assume it's a hostile |
| 465 // renderer and kill it. | 492 // renderer and kill it. |
| 466 if (value.size() > 512) { | 493 if (value.size() > 512) { |
| 467 bad_message::ReceivedBadMessage( | 494 bad_message::ReceivedBadMessage( |
| 468 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 495 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
| 469 return; | 496 return; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 | 701 |
| 675 void BluetoothDispatcherHost::OnWriteValueFailed( | 702 void BluetoothDispatcherHost::OnWriteValueFailed( |
| 676 int thread_id, | 703 int thread_id, |
| 677 int request_id, | 704 int request_id, |
| 678 device::BluetoothGattService::GattErrorCode error_code) { | 705 device::BluetoothGattService::GattErrorCode error_code) { |
| 679 Send(new BluetoothMsg_WriteCharacteristicValueError( | 706 Send(new BluetoothMsg_WriteCharacteristicValueError( |
| 680 thread_id, request_id, TranslateGATTError(error_code))); | 707 thread_id, request_id, TranslateGATTError(error_code))); |
| 681 } | 708 } |
| 682 | 709 |
| 683 } // namespace content | 710 } // namespace content |
| OLD | NEW |