| Index: content/browser/bluetooth/bluetooth_dispatcher_host.cc
|
| diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
|
| index 30d468b300e1ca6ef5e6691e9e62699cd2452547..b2e7ee3162b670a3c8a413bfdfc60f6324e0cdb8 100644
|
| --- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc
|
| +++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
|
| @@ -8,6 +8,13 @@
|
| // case.
|
| // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-connectgatt
|
|
|
| +// ID Not In Map Note:
|
| +// A service, characteristic, or descriptor ID not in the corresponding
|
| +// BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_,
|
| +// descriptor_to_characteristic_] implies a hostile renderer because a renderer
|
| +// obtains the corresponding ID from this class and it will be added to the map
|
| +// at that time.
|
| +
|
| #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
|
|
|
| #include "base/bind.h"
|
| @@ -204,6 +211,8 @@ bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
|
| IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic)
|
| IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue)
|
| IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue)
|
| + IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications)
|
| + IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| return handled;
|
| @@ -358,6 +367,15 @@ void BluetoothDispatcherHost::DeviceRemoved(device::BluetoothAdapter* adapter,
|
| }
|
| }
|
|
|
| +void BluetoothDispatcherHost::GattCharacteristicValueChanged(
|
| + device::BluetoothAdapter* adapter,
|
| + device::BluetoothGattCharacteristic* characteristic,
|
| + const std::vector<uint8>& value) {
|
| + // TODO(ortuno): Notify renderer the characteristic changed.
|
| + // http://crbug.com/529560
|
| + VLOG(1) << "Characteristic updated.";
|
| +}
|
| +
|
| void BluetoothDispatcherHost::OnRequestDevice(
|
| int thread_id,
|
| int request_id,
|
| @@ -517,11 +535,8 @@ void BluetoothDispatcherHost::OnGetCharacteristic(
|
| RecordGetCharacteristicCharacteristic(characteristic_uuid);
|
|
|
| auto device_iter = service_to_device_.find(service_instance_id);
|
| - // A service_instance_id not in the map implies a hostile renderer
|
| - // because a renderer obtains the service id from this class and
|
| - // it will be added to the map at that time.
|
| + // Kill the renderer, see "ID Not In Map Note" above.
|
| if (device_iter == service_to_device_.end()) {
|
| - // Kill the renderer
|
| bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
|
| return;
|
| }
|
| @@ -585,11 +600,9 @@ void BluetoothDispatcherHost::OnReadValue(
|
|
|
| auto characteristic_iter =
|
| characteristic_to_service_.find(characteristic_instance_id);
|
| - // A characteristic_instance_id not in the map implies a hostile renderer
|
| - // because a renderer obtains the characteristic id from this class and
|
| - // it will be added to the map at that time.
|
| +
|
| + // Kill the renderer, see "ID Not In Map Note" above.
|
| if (characteristic_iter == characteristic_to_service_.end()) {
|
| - // Kill the renderer
|
| bad_message::ReceivedBadMessage(this,
|
| bad_message::BDH_INVALID_CHARACTERISTIC_ID);
|
| return;
|
| @@ -657,9 +670,8 @@ void BluetoothDispatcherHost::OnWriteValue(
|
|
|
| auto characteristic_iter =
|
| characteristic_to_service_.find(characteristic_instance_id);
|
| - // A characteristic_instance_id not in the map implies a hostile renderer
|
| - // because a renderer obtains the characteristic id from this class and
|
| - // it will be added to the map at that time.
|
| +
|
| + // Kill the renderer, see "ID Not In Map Note" above.
|
| if (characteristic_iter == characteristic_to_service_.end()) {
|
| bad_message::ReceivedBadMessage(this,
|
| bad_message::BDH_INVALID_CHARACTERISTIC_ID);
|
| @@ -705,6 +717,94 @@ void BluetoothDispatcherHost::OnWriteValue(
|
| weak_ptr_on_ui_thread_, thread_id, request_id));
|
| }
|
|
|
| +void BluetoothDispatcherHost::OnStartNotifications(
|
| + int thread_id,
|
| + int request_id,
|
| + const std::string& characteristic_instance_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + RecordWebBluetoothFunctionCall(
|
| + UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
|
| +
|
| + // BluetoothDispatcher will never send a request for a characteristic
|
| + // already subscribed to notifications.
|
| + if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
|
| + characteristic_id_to_notify_session_.end()) {
|
| + bad_message::ReceivedBadMessage(
|
| + this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
|
| + return;
|
| + }
|
| +
|
| + // TODO(ortuno): Check if notify/indicate bit is set.
|
| + // http://crbug.com/538869
|
| +
|
| + auto characteristic_iter =
|
| + characteristic_to_service_.find(characteristic_instance_id);
|
| +
|
| + // Kill the renderer, see "ID Not In Map Note" above.
|
| + if (characteristic_iter == characteristic_to_service_.end()) {
|
| + bad_message::ReceivedBadMessage(this,
|
| + bad_message::BDH_INVALID_CHARACTERISTIC_ID);
|
| + return;
|
| + }
|
| +
|
| + const std::string& service_instance_id = characteristic_iter->second;
|
| + auto device_iter = service_to_device_.find(service_instance_id);
|
| + CHECK(device_iter != service_to_device_.end());
|
| +
|
| + device::BluetoothDevice* device =
|
| + adapter_->GetDevice(device_iter->second /* device_instance_id */);
|
| + if (device == nullptr) { // See "NETWORK_ERROR Note" above.
|
| + RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_DEVICE);
|
| + Send(new BluetoothMsg_StartNotificationsError(
|
| + thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
|
| + return;
|
| + }
|
| +
|
| + BluetoothGattService* service = device->GetGattService(service_instance_id);
|
| + if (service == nullptr) {
|
| + RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_SERVICE);
|
| + Send(new BluetoothMsg_StartNotificationsError(
|
| + thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
|
| + return;
|
| + }
|
| +
|
| + BluetoothGattCharacteristic* characteristic =
|
| + service->GetCharacteristic(characteristic_instance_id);
|
| + if (characteristic == nullptr) {
|
| + RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_CHARACTERISTIC);
|
| + Send(new BluetoothMsg_StartNotificationsError(
|
| + thread_id, request_id,
|
| + WebBluetoothError::CharacteristicNoLongerExists));
|
| + return;
|
| + }
|
| +
|
| + characteristic->StartNotifySession(
|
| + base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
|
| + weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
|
| + base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
|
| + weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
|
| +}
|
| +
|
| +void BluetoothDispatcherHost::OnStopNotifications(
|
| + int thread_id,
|
| + int request_id,
|
| + const std::string& characteristic_instance_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + RecordWebBluetoothFunctionCall(
|
| + UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS);
|
| +
|
| + auto notify_session_iter =
|
| + characteristic_id_to_notify_session_.find(characteristic_instance_id);
|
| + if (notify_session_iter == characteristic_id_to_notify_session_.end()) {
|
| + Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
|
| + return;
|
| + }
|
| + notify_session_iter->second->Stop(
|
| + base::Bind(&BluetoothDispatcherHost::OnStopNotifySession,
|
| + weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
|
| + characteristic_instance_id));
|
| +}
|
| +
|
| void BluetoothDispatcherHost::OnDiscoverySessionStarted(
|
| int chooser_id,
|
| scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
|
| @@ -946,6 +1046,35 @@ void BluetoothDispatcherHost::OnWriteValueFailed(
|
| TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)));
|
| }
|
|
|
| +void BluetoothDispatcherHost::OnStartNotifySessionSuccess(
|
| + int thread_id,
|
| + int request_id,
|
| + scoped_ptr<device::BluetoothGattNotifySession> notify_session) {
|
| + RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS);
|
| +
|
| + characteristic_id_to_notify_session_.insert(
|
| + notify_session->GetCharacteristicIdentifier(), notify_session.Pass());
|
| + Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id));
|
| +}
|
| +
|
| +void BluetoothDispatcherHost::OnStartNotifySessionFailed(
|
| + int thread_id,
|
| + int request_id,
|
| + device::BluetoothGattService::GattErrorCode error_code) {
|
| + // TranslateGATTError calls RecordGATTOperationOutcome.
|
| + Send(new BluetoothMsg_StartNotificationsError(
|
| + thread_id, request_id,
|
| + TranslateGATTError(error_code, UMAGATTOperation::START_NOTIFICATIONS)));
|
| +}
|
| +
|
| +void BluetoothDispatcherHost::OnStopNotifySession(
|
| + int thread_id,
|
| + int request_id,
|
| + const std::string& characteristic_instance_id) {
|
| + characteristic_id_to_notify_session_.erase(characteristic_instance_id);
|
| + Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
|
| +}
|
| +
|
| void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| NOTIMPLEMENTED();
|
|
|