| 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 // ID Not In Map Note: | 5 // ID Not In Map Note: |
| 6 // A service, characteristic, or descriptor ID not in the corresponding | 6 // A service, characteristic, or descriptor ID not in the corresponding |
| 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, | 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, |
| 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer | 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 | 9 // obtains the corresponding ID from this class and it will be added to the map |
| 10 // at that time. | 10 // at that time. |
| 11 | 11 |
| 12 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 12 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
| 13 | 13 |
| 14 #include <stddef.h> | 14 #include <stddef.h> |
| 15 | 15 |
| 16 #include <utility> | 16 #include <utility> |
| 17 | 17 |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/thread_task_runner_handle.h" | 21 #include "base/thread_task_runner_handle.h" |
| 22 #include "content/browser/bad_message.h" | 22 #include "content/browser/bad_message.h" |
| 23 #include "content/browser/bluetooth/bluetooth_blacklist.h" | 23 #include "content/browser/bluetooth/bluetooth_blacklist.h" |
| 24 #include "content/browser/bluetooth/bluetooth_metrics.h" | 24 #include "content/browser/bluetooth/bluetooth_metrics.h" |
| 25 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" | 25 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" |
| 26 #include "content/browser/frame_host/render_frame_host_impl.h" | 26 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 27 #include "content/common/bluetooth/bluetooth_messages.h" | |
| 28 #include "content/public/browser/content_browser_client.h" | 27 #include "content/public/browser/content_browser_client.h" |
| 29 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 30 #include "content/public/browser/web_contents_delegate.h" | 29 #include "content/public/browser/web_contents_delegate.h" |
| 31 #include "device/bluetooth/bluetooth_adapter.h" | 30 #include "device/bluetooth/bluetooth_adapter.h" |
| 32 #include "device/bluetooth/bluetooth_adapter_factory.h" | 31 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 33 #include "device/bluetooth/bluetooth_device.h" | 32 #include "device/bluetooth/bluetooth_device.h" |
| 34 #include "device/bluetooth/bluetooth_discovery_session.h" | 33 #include "device/bluetooth/bluetooth_discovery_session.h" |
| 35 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 34 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 36 #include "device/bluetooth/bluetooth_gatt_service.h" | 35 #include "device/bluetooth/bluetooth_gatt_service.h" |
| 37 | 36 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 bool handled = true; | 302 bool handled = true; |
| 304 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) | 303 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) |
| 305 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) | 304 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) |
| 306 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerConnect, OnGATTServerConnect) | 305 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerConnect, OnGATTServerConnect) |
| 307 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerDisconnect, | 306 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerDisconnect, |
| 308 OnGATTServerDisconnect) | 307 OnGATTServerDisconnect) |
| 309 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) | 308 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) |
| 310 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) | 309 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) |
| 311 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristics, OnGetCharacteristics) | 310 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristics, OnGetCharacteristics) |
| 312 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) | 311 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) |
| 313 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) | |
| 314 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications) | 312 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications) |
| 315 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications) | 313 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications) |
| 316 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RegisterCharacteristic, | 314 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RegisterCharacteristic, |
| 317 OnRegisterCharacteristicObject); | 315 OnRegisterCharacteristicObject); |
| 318 IPC_MESSAGE_HANDLER(BluetoothHostMsg_UnregisterCharacteristic, | 316 IPC_MESSAGE_HANDLER(BluetoothHostMsg_UnregisterCharacteristic, |
| 319 OnUnregisterCharacteristicObject); | 317 OnUnregisterCharacteristicObject); |
| 320 IPC_MESSAGE_UNHANDLED(handled = false) | 318 IPC_MESSAGE_UNHANDLED(handled = false) |
| 321 IPC_END_MESSAGE_MAP() | 319 IPC_END_MESSAGE_MAP() |
| 322 return handled; | 320 return handled; |
| 323 } | 321 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 const int thread_id; | 400 const int thread_id; |
| 403 const int request_id; | 401 const int request_id; |
| 404 const int frame_routing_id; | 402 const int frame_routing_id; |
| 405 const url::Origin origin; | 403 const url::Origin origin; |
| 406 const std::vector<BluetoothScanFilter> filters; | 404 const std::vector<BluetoothScanFilter> filters; |
| 407 const std::vector<BluetoothUUID> optional_services; | 405 const std::vector<BluetoothUUID> optional_services; |
| 408 scoped_ptr<BluetoothChooser> chooser; | 406 scoped_ptr<BluetoothChooser> chooser; |
| 409 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; | 407 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; |
| 410 }; | 408 }; |
| 411 | 409 |
| 412 struct BluetoothDispatcherHost::CacheQueryResult { | 410 BluetoothDispatcherHost::CacheQueryResult::CacheQueryResult() |
| 413 CacheQueryResult() | 411 : device(nullptr), |
| 414 : device(nullptr), | 412 service(nullptr), |
| 415 service(nullptr), | 413 characteristic(nullptr), |
| 416 characteristic(nullptr), | 414 outcome(CacheQueryOutcome::SUCCESS) {} |
| 417 outcome(CacheQueryOutcome::SUCCESS) {} | 415 |
| 418 CacheQueryResult(CacheQueryOutcome outcome) | 416 BluetoothDispatcherHost::CacheQueryResult::CacheQueryResult( |
| 419 : device(nullptr), | 417 CacheQueryOutcome outcome) |
| 420 service(nullptr), | 418 : device(nullptr), |
| 421 characteristic(nullptr), | 419 service(nullptr), |
| 422 outcome(outcome) {} | 420 characteristic(nullptr), |
| 423 ~CacheQueryResult() {} | 421 outcome(outcome) {} |
| 424 WebBluetoothError GetWebError() const { | 422 |
| 425 switch (outcome) { | 423 BluetoothDispatcherHost::CacheQueryResult::~CacheQueryResult() {} |
| 426 case CacheQueryOutcome::SUCCESS: | 424 |
| 427 case CacheQueryOutcome::BAD_RENDERER: | 425 WebBluetoothError BluetoothDispatcherHost::CacheQueryResult::GetWebError() |
| 428 NOTREACHED(); | 426 const { |
| 429 return WebBluetoothError::DeviceNoLongerInRange; | 427 switch (outcome) { |
| 430 case CacheQueryOutcome::NO_DEVICE: | 428 case CacheQueryOutcome::SUCCESS: |
| 431 return WebBluetoothError::DeviceNoLongerInRange; | 429 case CacheQueryOutcome::BAD_RENDERER: |
| 432 case CacheQueryOutcome::NO_SERVICE: | 430 NOTREACHED(); |
| 433 return WebBluetoothError::ServiceNoLongerExists; | 431 return WebBluetoothError::DeviceNoLongerInRange; |
| 434 case CacheQueryOutcome::NO_CHARACTERISTIC: | 432 case CacheQueryOutcome::NO_DEVICE: |
| 435 return WebBluetoothError::CharacteristicNoLongerExists; | 433 return WebBluetoothError::DeviceNoLongerInRange; |
| 436 } | 434 case CacheQueryOutcome::NO_SERVICE: |
| 437 NOTREACHED(); | 435 return WebBluetoothError::ServiceNoLongerExists; |
| 438 return WebBluetoothError::DeviceNoLongerInRange; | 436 case CacheQueryOutcome::NO_CHARACTERISTIC: |
| 437 return WebBluetoothError::CharacteristicNoLongerExists; |
| 439 } | 438 } |
| 440 | 439 NOTREACHED(); |
| 441 device::BluetoothDevice* device; | 440 return WebBluetoothError::DeviceNoLongerInRange; |
| 442 device::BluetoothGattService* service; | 441 } |
| 443 device::BluetoothGattCharacteristic* characteristic; | |
| 444 CacheQueryOutcome outcome; | |
| 445 }; | |
| 446 | 442 |
| 447 struct BluetoothDispatcherHost::PrimaryServicesRequest { | 443 struct BluetoothDispatcherHost::PrimaryServicesRequest { |
| 448 enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES }; | 444 enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES }; |
| 449 | 445 |
| 450 PrimaryServicesRequest(int thread_id, | 446 PrimaryServicesRequest(int thread_id, |
| 451 int request_id, | 447 int request_id, |
| 452 const std::string& service_uuid, | 448 const std::string& service_uuid, |
| 453 PrimaryServicesRequest::CallingFunction func) | 449 PrimaryServicesRequest::CallingFunction func) |
| 454 : thread_id(thread_id), | 450 : thread_id(thread_id), |
| 455 request_id(request_id), | 451 request_id(request_id), |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 return; | 964 return; |
| 969 } | 965 } |
| 970 | 966 |
| 971 query_result.characteristic->ReadRemoteCharacteristic( | 967 query_result.characteristic->ReadRemoteCharacteristic( |
| 972 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 968 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
| 973 weak_ptr_on_ui_thread_, thread_id, request_id), | 969 weak_ptr_on_ui_thread_, thread_id, request_id), |
| 974 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 970 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
| 975 weak_ptr_on_ui_thread_, thread_id, request_id)); | 971 weak_ptr_on_ui_thread_, thread_id, request_id)); |
| 976 } | 972 } |
| 977 | 973 |
| 978 void BluetoothDispatcherHost::OnWriteValue( | |
| 979 int thread_id, | |
| 980 int request_id, | |
| 981 int frame_routing_id, | |
| 982 const std::string& characteristic_instance_id, | |
| 983 const std::vector<uint8_t>& value) { | |
| 984 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 985 RecordWebBluetoothFunctionCall( | |
| 986 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
| 987 | |
| 988 // Length check per step 3 of writeValue algorithm: | |
| 989 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac
teristic-writevalue | |
| 990 // We perform the length check on the renderer side. So if we | |
| 991 // get a value with length > 512, we can assume it's a hostile | |
| 992 // renderer and kill it. | |
| 993 if (value.size() > 512) { | |
| 994 bad_message::ReceivedBadMessage( | |
| 995 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | |
| 996 return; | |
| 997 } | |
| 998 | |
| 999 const CacheQueryResult query_result = QueryCacheForCharacteristic( | |
| 1000 GetOrigin(frame_routing_id), characteristic_instance_id); | |
| 1001 | |
| 1002 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
| 1003 return; | |
| 1004 } | |
| 1005 | |
| 1006 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | |
| 1007 RecordCharacteristicWriteValueOutcome(query_result.outcome); | |
| 1008 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
| 1009 thread_id, request_id, query_result.GetWebError())); | |
| 1010 return; | |
| 1011 } | |
| 1012 | |
| 1013 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | |
| 1014 query_result.characteristic->GetUUID())) { | |
| 1015 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::BLACKLISTED); | |
| 1016 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
| 1017 thread_id, request_id, WebBluetoothError::BlacklistedWrite)); | |
| 1018 return; | |
| 1019 } | |
| 1020 | |
| 1021 query_result.characteristic->WriteRemoteCharacteristic( | |
| 1022 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | |
| 1023 weak_ptr_on_ui_thread_, thread_id, request_id), | |
| 1024 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | |
| 1025 weak_ptr_on_ui_thread_, thread_id, request_id)); | |
| 1026 } | |
| 1027 | |
| 1028 void BluetoothDispatcherHost::OnStartNotifications( | 974 void BluetoothDispatcherHost::OnStartNotifications( |
| 1029 int thread_id, | 975 int thread_id, |
| 1030 int request_id, | 976 int request_id, |
| 1031 int frame_routing_id, | 977 int frame_routing_id, |
| 1032 const std::string& characteristic_instance_id) { | 978 const std::string& characteristic_instance_id) { |
| 1033 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 979 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1034 RecordWebBluetoothFunctionCall( | 980 RecordWebBluetoothFunctionCall( |
| 1035 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); | 981 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
| 1036 | 982 |
| 1037 // BluetoothDispatcher will never send a request for a characteristic | 983 // BluetoothDispatcher will never send a request for a characteristic |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 int thread_id, | 1444 int thread_id, |
| 1499 int request_id, | 1445 int request_id, |
| 1500 device::BluetoothGattService::GattErrorCode error_code) { | 1446 device::BluetoothGattService::GattErrorCode error_code) { |
| 1501 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1447 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1502 // TranslateGATTError calls RecordGATTOperationOutcome. | 1448 // TranslateGATTError calls RecordGATTOperationOutcome. |
| 1503 Send(new BluetoothMsg_ReadCharacteristicValueError( | 1449 Send(new BluetoothMsg_ReadCharacteristicValueError( |
| 1504 thread_id, request_id, | 1450 thread_id, request_id, |
| 1505 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_READ))); | 1451 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_READ))); |
| 1506 } | 1452 } |
| 1507 | 1453 |
| 1508 void BluetoothDispatcherHost::OnWriteValueSuccess(int thread_id, | |
| 1509 int request_id) { | |
| 1510 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 1511 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS); | |
| 1512 Send(new BluetoothMsg_WriteCharacteristicValueSuccess(thread_id, request_id)); | |
| 1513 } | |
| 1514 | |
| 1515 void BluetoothDispatcherHost::OnWriteValueFailed( | |
| 1516 int thread_id, | |
| 1517 int request_id, | |
| 1518 device::BluetoothGattService::GattErrorCode error_code) { | |
| 1519 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 1520 // TranslateGATTError calls RecordGATTOperationOutcome. | |
| 1521 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
| 1522 thread_id, request_id, | |
| 1523 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); | |
| 1524 } | |
| 1525 | |
| 1526 void BluetoothDispatcherHost::OnStartNotifySessionSuccess( | 1454 void BluetoothDispatcherHost::OnStartNotifySessionSuccess( |
| 1527 int thread_id, | 1455 int thread_id, |
| 1528 int request_id, | 1456 int request_id, |
| 1529 scoped_ptr<device::BluetoothGattNotifySession> notify_session) { | 1457 scoped_ptr<device::BluetoothGattNotifySession> notify_session) { |
| 1530 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS); | 1458 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS); |
| 1531 | 1459 |
| 1532 // Copy Characteristic Instance ID before passing scoped pointer because | 1460 // Copy Characteristic Instance ID before passing scoped pointer because |
| 1533 // compilers may evaluate arguments in any order. | 1461 // compilers may evaluate arguments in any order. |
| 1534 const std::string characteristic_instance_id = | 1462 const std::string characteristic_instance_id = |
| 1535 notify_session->GetCharacteristicIdentifier(); | 1463 notify_session->GetCharacteristicIdentifier(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 | 1592 |
| 1665 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( | 1593 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( |
| 1666 int frame_routing_id, | 1594 int frame_routing_id, |
| 1667 const std::string& characteristic_instance_id) { | 1595 const std::string& characteristic_instance_id) { |
| 1668 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | 1596 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), |
| 1669 characteristic_instance_id) | 1597 characteristic_instance_id) |
| 1670 .outcome != CacheQueryOutcome::BAD_RENDERER; | 1598 .outcome != CacheQueryOutcome::BAD_RENDERER; |
| 1671 } | 1599 } |
| 1672 | 1600 |
| 1673 } // namespace content | 1601 } // namespace content |
| OLD | NEW |