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 // 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 |