Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2010)

Unified Diff: content/browser/bluetooth/bluetooth_dispatcher_host.cc

Issue 1334763002: bluetooth: Subscribe to notifications (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-origin
Patch Set: Fix global interface test Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
« no previous file with comments | « content/browser/bluetooth/bluetooth_dispatcher_host.h ('k') | content/browser/bluetooth/bluetooth_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698