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" | |
25 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" | 24 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" |
26 #include "content/browser/frame_host/render_frame_host_impl.h" | 25 #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" | 26 #include "content/public/browser/content_browser_client.h" |
29 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
30 #include "content/public/browser/web_contents_delegate.h" | 28 #include "content/public/browser/web_contents_delegate.h" |
31 #include "device/bluetooth/bluetooth_adapter.h" | 29 #include "device/bluetooth/bluetooth_adapter.h" |
32 #include "device/bluetooth/bluetooth_adapter_factory.h" | 30 #include "device/bluetooth/bluetooth_adapter_factory.h" |
33 #include "device/bluetooth/bluetooth_device.h" | 31 #include "device/bluetooth/bluetooth_device.h" |
34 #include "device/bluetooth/bluetooth_discovery_session.h" | 32 #include "device/bluetooth/bluetooth_discovery_session.h" |
35 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 33 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
36 #include "device/bluetooth/bluetooth_gatt_service.h" | 34 #include "device/bluetooth/bluetooth_gatt_service.h" |
37 | 35 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 RecordConnectGATTOutcome(UMAConnectGATTOutcome::WRITE_NOT_PERMITTED); | 160 RecordConnectGATTOutcome(UMAConnectGATTOutcome::WRITE_NOT_PERMITTED); |
163 return WebBluetoothError::CONNECT_WRITE_NOT_PERMITTED; | 161 return WebBluetoothError::CONNECT_WRITE_NOT_PERMITTED; |
164 case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES: | 162 case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES: |
165 NOTREACHED(); | 163 NOTREACHED(); |
166 return WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE; | 164 return WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE; |
167 } | 165 } |
168 NOTREACHED(); | 166 NOTREACHED(); |
169 return WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE; | 167 return WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE; |
170 } | 168 } |
171 | 169 |
172 blink::WebBluetoothError TranslateGATTError( | 170 WebBluetoothError TranslateGATTError( |
173 BluetoothGattService::GattErrorCode error_code, | 171 BluetoothGattService::GattErrorCode error_code, |
174 UMAGATTOperation operation) { | 172 UMAGATTOperation operation) { |
175 switch (error_code) { | 173 switch (error_code) { |
176 case BluetoothGattService::GATT_ERROR_UNKNOWN: | 174 case BluetoothGattService::GATT_ERROR_UNKNOWN: |
177 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); | 175 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); |
178 return blink::WebBluetoothError::GATT_UNKNOWN_ERROR; | 176 return blink::WebBluetoothError::GATT_UNKNOWN_ERROR; |
179 case BluetoothGattService::GATT_ERROR_FAILED: | 177 case BluetoothGattService::GATT_ERROR_FAILED: |
180 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); | 178 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); |
181 return blink::WebBluetoothError::GATT_UNKNOWN_FAILURE; | 179 return blink::WebBluetoothError::GATT_UNKNOWN_FAILURE; |
182 case BluetoothGattService::GATT_ERROR_IN_PROGRESS: | 180 case BluetoothGattService::GATT_ERROR_IN_PROGRESS: |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 bool handled = true; | 301 bool handled = true; |
304 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) | 302 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) |
305 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) | 303 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) |
306 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerConnect, OnGATTServerConnect) | 304 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerConnect, OnGATTServerConnect) |
307 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerDisconnect, | 305 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GATTServerDisconnect, |
308 OnGATTServerDisconnect) | 306 OnGATTServerDisconnect) |
309 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) | 307 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) |
310 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) | 308 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) |
311 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristics, OnGetCharacteristics) | 309 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristics, OnGetCharacteristics) |
312 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) | 310 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue) |
313 IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue) | |
314 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications) | 311 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications) |
315 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications) | 312 IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications) |
316 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RegisterCharacteristic, | 313 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RegisterCharacteristic, |
317 OnRegisterCharacteristicObject); | 314 OnRegisterCharacteristicObject); |
318 IPC_MESSAGE_HANDLER(BluetoothHostMsg_UnregisterCharacteristic, | 315 IPC_MESSAGE_HANDLER(BluetoothHostMsg_UnregisterCharacteristic, |
319 OnUnregisterCharacteristicObject); | 316 OnUnregisterCharacteristicObject); |
320 IPC_MESSAGE_UNHANDLED(handled = false) | 317 IPC_MESSAGE_UNHANDLED(handled = false) |
321 IPC_END_MESSAGE_MAP() | 318 IPC_END_MESSAGE_MAP() |
322 return handled; | 319 return handled; |
323 } | 320 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 const int thread_id; | 399 const int thread_id; |
403 const int request_id; | 400 const int request_id; |
404 const int frame_routing_id; | 401 const int frame_routing_id; |
405 const url::Origin origin; | 402 const url::Origin origin; |
406 const std::vector<BluetoothScanFilter> filters; | 403 const std::vector<BluetoothScanFilter> filters; |
407 const std::vector<BluetoothUUID> optional_services; | 404 const std::vector<BluetoothUUID> optional_services; |
408 scoped_ptr<BluetoothChooser> chooser; | 405 scoped_ptr<BluetoothChooser> chooser; |
409 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; | 406 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; |
410 }; | 407 }; |
411 | 408 |
412 struct BluetoothDispatcherHost::CacheQueryResult { | 409 BluetoothDispatcherHost::CacheQueryResult::CacheQueryResult() {} |
413 CacheQueryResult() | 410 |
414 : device(nullptr), | 411 BluetoothDispatcherHost::CacheQueryResult::CacheQueryResult( |
415 service(nullptr), | 412 CacheQueryOutcome outcome) |
416 characteristic(nullptr), | 413 : outcome(outcome) {} |
417 outcome(CacheQueryOutcome::SUCCESS) {} | 414 |
418 CacheQueryResult(CacheQueryOutcome outcome) | 415 BluetoothDispatcherHost::CacheQueryResult::~CacheQueryResult() {} |
419 : device(nullptr), | 416 |
420 service(nullptr), | 417 blink::WebBluetoothError |
Jeffrey Yasskin
2016/03/29 20:30:02
You don't need the blink:: here, due to the 'using
ortuno
2016/03/29 22:14:03
Done.
| |
421 characteristic(nullptr), | 418 BluetoothDispatcherHost::CacheQueryResult::GetWebError() const { |
422 outcome(outcome) {} | 419 switch (outcome) { |
423 ~CacheQueryResult() {} | 420 case CacheQueryOutcome::SUCCESS: |
424 WebBluetoothError GetWebError() const { | 421 case CacheQueryOutcome::BAD_RENDERER: |
425 switch (outcome) { | 422 NOTREACHED(); |
426 case CacheQueryOutcome::SUCCESS: | 423 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; |
427 case CacheQueryOutcome::BAD_RENDERER: | 424 case CacheQueryOutcome::NO_DEVICE: |
428 NOTREACHED(); | 425 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; |
429 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | 426 case CacheQueryOutcome::NO_SERVICE: |
430 case CacheQueryOutcome::NO_DEVICE: | 427 return WebBluetoothError::SERVICE_NO_LONGER_EXISTS; |
431 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | 428 case CacheQueryOutcome::NO_CHARACTERISTIC: |
432 case CacheQueryOutcome::NO_SERVICE: | 429 return WebBluetoothError::CHARACTERISTIC_NO_LONGER_EXISTS; |
433 return WebBluetoothError::SERVICE_NO_LONGER_EXISTS; | |
434 case CacheQueryOutcome::NO_CHARACTERISTIC: | |
435 return WebBluetoothError::CHARACTERISTIC_NO_LONGER_EXISTS; | |
436 } | |
437 NOTREACHED(); | |
438 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
439 } | 430 } |
440 | 431 NOTREACHED(); |
441 device::BluetoothDevice* device; | 432 return WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; |
442 device::BluetoothGattService* service; | 433 } |
443 device::BluetoothGattCharacteristic* characteristic; | |
444 CacheQueryOutcome outcome; | |
445 }; | |
446 | 434 |
447 struct BluetoothDispatcherHost::PrimaryServicesRequest { | 435 struct BluetoothDispatcherHost::PrimaryServicesRequest { |
448 enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES }; | 436 enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES }; |
449 | 437 |
450 PrimaryServicesRequest(int thread_id, | 438 PrimaryServicesRequest(int thread_id, |
451 int request_id, | 439 int request_id, |
452 const std::string& service_uuid, | 440 const std::string& service_uuid, |
453 PrimaryServicesRequest::CallingFunction func) | 441 PrimaryServicesRequest::CallingFunction func) |
454 : thread_id(thread_id), | 442 : thread_id(thread_id), |
455 request_id(request_id), | 443 request_id(request_id), |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
970 return; | 958 return; |
971 } | 959 } |
972 | 960 |
973 query_result.characteristic->ReadRemoteCharacteristic( | 961 query_result.characteristic->ReadRemoteCharacteristic( |
974 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 962 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
975 weak_ptr_on_ui_thread_, thread_id, request_id), | 963 weak_ptr_on_ui_thread_, thread_id, request_id), |
976 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 964 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
977 weak_ptr_on_ui_thread_, thread_id, request_id)); | 965 weak_ptr_on_ui_thread_, thread_id, request_id)); |
978 } | 966 } |
979 | 967 |
980 void BluetoothDispatcherHost::OnWriteValue( | |
981 int thread_id, | |
982 int request_id, | |
983 int frame_routing_id, | |
984 const std::string& characteristic_instance_id, | |
985 const std::vector<uint8_t>& value) { | |
986 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
987 RecordWebBluetoothFunctionCall( | |
988 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
989 | |
990 // Length check per step 3 of writeValue algorithm: | |
991 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | |
992 // We perform the length check on the renderer side. So if we | |
993 // get a value with length > 512, we can assume it's a hostile | |
994 // renderer and kill it. | |
995 if (value.size() > 512) { | |
996 bad_message::ReceivedBadMessage( | |
997 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | |
998 return; | |
999 } | |
1000 | |
1001 const CacheQueryResult query_result = QueryCacheForCharacteristic( | |
1002 GetOrigin(frame_routing_id), characteristic_instance_id); | |
1003 | |
1004 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
1005 return; | |
1006 } | |
1007 | |
1008 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | |
1009 RecordCharacteristicWriteValueOutcome(query_result.outcome); | |
1010 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
1011 thread_id, request_id, query_result.GetWebError())); | |
1012 return; | |
1013 } | |
1014 | |
1015 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | |
1016 query_result.characteristic->GetUUID())) { | |
1017 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::BLACKLISTED); | |
1018 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
1019 thread_id, request_id, WebBluetoothError::BLACKLISTED_WRITE)); | |
1020 return; | |
1021 } | |
1022 | |
1023 query_result.characteristic->WriteRemoteCharacteristic( | |
1024 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | |
1025 weak_ptr_on_ui_thread_, thread_id, request_id), | |
1026 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | |
1027 weak_ptr_on_ui_thread_, thread_id, request_id)); | |
1028 } | |
1029 | |
1030 void BluetoothDispatcherHost::OnStartNotifications( | 968 void BluetoothDispatcherHost::OnStartNotifications( |
1031 int thread_id, | 969 int thread_id, |
1032 int request_id, | 970 int request_id, |
1033 int frame_routing_id, | 971 int frame_routing_id, |
1034 const std::string& characteristic_instance_id) { | 972 const std::string& characteristic_instance_id) { |
1035 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 973 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1036 RecordWebBluetoothFunctionCall( | 974 RecordWebBluetoothFunctionCall( |
1037 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); | 975 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
1038 | 976 |
1039 // BluetoothDispatcher will never send a request for a characteristic | 977 // BluetoothDispatcher will never send a request for a characteristic |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1501 int thread_id, | 1439 int thread_id, |
1502 int request_id, | 1440 int request_id, |
1503 device::BluetoothGattService::GattErrorCode error_code) { | 1441 device::BluetoothGattService::GattErrorCode error_code) { |
1504 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1442 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1505 // TranslateGATTError calls RecordGATTOperationOutcome. | 1443 // TranslateGATTError calls RecordGATTOperationOutcome. |
1506 Send(new BluetoothMsg_ReadCharacteristicValueError( | 1444 Send(new BluetoothMsg_ReadCharacteristicValueError( |
1507 thread_id, request_id, | 1445 thread_id, request_id, |
1508 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_READ))); | 1446 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_READ))); |
1509 } | 1447 } |
1510 | 1448 |
1511 void BluetoothDispatcherHost::OnWriteValueSuccess(int thread_id, | |
1512 int request_id) { | |
1513 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
1514 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS); | |
1515 Send(new BluetoothMsg_WriteCharacteristicValueSuccess(thread_id, request_id)); | |
1516 } | |
1517 | |
1518 void BluetoothDispatcherHost::OnWriteValueFailed( | |
1519 int thread_id, | |
1520 int request_id, | |
1521 device::BluetoothGattService::GattErrorCode error_code) { | |
1522 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
1523 // TranslateGATTError calls RecordGATTOperationOutcome. | |
1524 Send(new BluetoothMsg_WriteCharacteristicValueError( | |
1525 thread_id, request_id, | |
1526 TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE))); | |
1527 } | |
1528 | |
1529 void BluetoothDispatcherHost::OnStartNotifySessionSuccess( | 1449 void BluetoothDispatcherHost::OnStartNotifySessionSuccess( |
1530 int thread_id, | 1450 int thread_id, |
1531 int request_id, | 1451 int request_id, |
1532 scoped_ptr<device::BluetoothGattNotifySession> notify_session) { | 1452 scoped_ptr<device::BluetoothGattNotifySession> notify_session) { |
1533 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS); | 1453 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS); |
1534 | 1454 |
1535 // Copy Characteristic Instance ID before passing scoped pointer because | 1455 // Copy Characteristic Instance ID before passing scoped pointer because |
1536 // compilers may evaluate arguments in any order. | 1456 // compilers may evaluate arguments in any order. |
1537 const std::string characteristic_instance_id = | 1457 const std::string characteristic_instance_id = |
1538 notify_session->GetCharacteristicIdentifier(); | 1458 notify_session->GetCharacteristicIdentifier(); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1667 | 1587 |
1668 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( | 1588 bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance( |
1669 int frame_routing_id, | 1589 int frame_routing_id, |
1670 const std::string& characteristic_instance_id) { | 1590 const std::string& characteristic_instance_id) { |
1671 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | 1591 return QueryCacheForCharacteristic(GetOrigin(frame_routing_id), |
1672 characteristic_instance_id) | 1592 characteristic_instance_id) |
1673 .outcome != CacheQueryOutcome::BAD_RENDERER; | 1593 .outcome != CacheQueryOutcome::BAD_RENDERER; |
1674 } | 1594 } |
1675 | 1595 |
1676 } // namespace content | 1596 } // namespace content |
OLD | NEW |