 Chromium Code Reviews
 Chromium Code Reviews Issue 1382743002:
  bluetooth: Add characteristicvaluechanged event  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-notifications-1
    
  
    Issue 1382743002:
  bluetooth: Add characteristicvaluechanged event  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-notifications-1| 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 #include "content/renderer/bluetooth/bluetooth_dispatcher.h" | 5 #include "content/renderer/bluetooth/bluetooth_dispatcher.h" | 
| 6 | 6 | 
| 7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" | 
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" | 
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" | 
| 10 #include "base/thread_task_runner_handle.h" | 10 #include "base/thread_task_runner_handle.h" | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, | 170 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, | 
| 171 OnWriteValueSuccess); | 171 OnWriteValueSuccess); | 
| 172 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, | 172 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, | 
| 173 OnWriteValueError); | 173 OnWriteValueError); | 
| 174 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsSuccess, | 174 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsSuccess, | 
| 175 OnStartNotificationsSuccess) | 175 OnStartNotificationsSuccess) | 
| 176 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsError, | 176 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsError, | 
| 177 OnStartNotificationsError) | 177 OnStartNotificationsError) | 
| 178 IPC_MESSAGE_HANDLER(BluetoothMsg_StopNotificationsSuccess, | 178 IPC_MESSAGE_HANDLER(BluetoothMsg_StopNotificationsSuccess, | 
| 179 OnStopNotificationsSuccess) | 179 OnStopNotificationsSuccess) | 
| 180 IPC_MESSAGE_HANDLER(BluetoothMsg_CharacteristicValueChanged, | |
| 181 OnCharacteristicValueChanged) | |
| 180 IPC_MESSAGE_UNHANDLED(handled = false) | 182 IPC_MESSAGE_UNHANDLED(handled = false) | 
| 181 IPC_END_MESSAGE_MAP() | 183 IPC_END_MESSAGE_MAP() | 
| 182 DCHECK(handled) << "Unhandled message:" << msg.type(); | 184 DCHECK(handled) << "Unhandled message:" << msg.type(); | 
| 183 } | 185 } | 
| 184 | 186 | 
| 185 void BluetoothDispatcher::requestDevice( | 187 void BluetoothDispatcher::requestDevice( | 
| 186 int frame_routing_id, | 188 int frame_routing_id, | 
| 187 const WebRequestDeviceOptions& options, | 189 const WebRequestDeviceOptions& options, | 
| 188 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { | 190 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { | 
| 189 int request_id = pending_requests_.Add(callbacks); | 191 int request_id = pending_requests_.Add(callbacks); | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 characteristic_instance_id.utf8())) { | 290 characteristic_instance_id.utf8())) { | 
| 289 return; | 291 return; | 
| 290 } | 292 } | 
| 291 | 293 | 
| 292 ResolveOrSendStopNotificationsRequest(request_id); | 294 ResolveOrSendStopNotificationsRequest(request_id); | 
| 293 } | 295 } | 
| 294 | 296 | 
| 295 void BluetoothDispatcher::characteristicObjectRemoved( | 297 void BluetoothDispatcher::characteristicObjectRemoved( | 
| 296 const blink::WebString& characteristic_instance_id, | 298 const blink::WebString& characteristic_instance_id, | 
| 297 blink::WebBluetoothGATTCharacteristic* characteristic) { | 299 blink::WebBluetoothGATTCharacteristic* characteristic) { | 
| 298 // A characteristic object is in the queue waiting for a response | 300 // We need to remove references to the object from the following: | 
| 299 // or in the set of active notifications. | 301 // 1) The set of active characteristics | 
| 302 // 2) The queue waiting for a response | |
| 303 // 3) The set of active notifications | |
| 300 | 304 | 
| 305 // 1 | |
| 306 // TODO(ortuno): We should only unregister a characteristic once | |
| 
Jeffrey Yasskin
2015/10/15 23:00:51
"should only unregister" sounds like we're unregis
 
ortuno
2015/10/16 01:24:21
Linked to multiple frames bug. Done.
 | |
| 307 // there are no characteristic objects that have listeners attached. | |
| 308 // http://crbug.com/541390 | |
| 
Jeffrey Yasskin
2015/10/15 23:00:51
Nit: Prefer https links.
 
ortuno
2015/10/16 01:24:21
Done.
 | |
| 309 UnregisterCharacteristicObject(characteristic_instance_id); | |
| 310 | |
| 311 // 2 | |
| 301 // If the object is in the queue we null the characteristic. If this is the | 312 // If the object is in the queue we null the characteristic. If this is the | 
| 302 // first object waiting for a response OnStartNotificationsSuccess will make | 313 // first object waiting for a response OnStartNotificationsSuccess will make | 
| 303 // sure not to add the characteristic to the map and it will queue a Stop | 314 // sure not to add the characteristic to the map and it will queue a Stop | 
| 304 // request. Otherwise ResolveOrSendStartNotificationRequest will make sure not | 315 // request. Otherwise ResolveOrSendStartNotificationRequest will make sure not | 
| 305 // to add it to active notification subscriptions. | 316 // to add it to active notification subscriptions. | 
| 306 bool found = false; | 317 bool found = false; | 
| 307 for (IDMap<BluetoothNotificationsRequest, IDMapOwnPointer>::iterator iter( | 318 for (IDMap<BluetoothNotificationsRequest, IDMapOwnPointer>::iterator iter( | 
| 308 &pending_notifications_requests_); | 319 &pending_notifications_requests_); | 
| 309 !iter.IsAtEnd(); iter.Advance()) { | 320 !iter.IsAtEnd(); iter.Advance()) { | 
| 310 if (iter.GetCurrentValue()->characteristic == characteristic) { | 321 if (iter.GetCurrentValue()->characteristic == characteristic) { | 
| 311 found = true; | 322 found = true; | 
| 312 iter.GetCurrentValue()->characteristic = nullptr; | 323 iter.GetCurrentValue()->characteristic = nullptr; | 
| 313 } | 324 } | 
| 314 } | 325 } | 
| 315 | 326 | 
| 316 if (found) { | 327 if (found) { | 
| 317 // A characteristic will never be in the set of active notifications | 328 // A characteristic will never be in the set of active notifications | 
| 318 // and in the queue at the same time. | 329 // and in the queue at the same time. | 
| 319 auto subscriptions_iter = active_notification_subscriptions_.find( | 330 auto subscriptions_iter = active_notification_subscriptions_.find( | 
| 320 characteristic_instance_id.utf8()); | 331 characteristic_instance_id.utf8()); | 
| 321 if (subscriptions_iter != active_notification_subscriptions_.end()) { | 332 if (subscriptions_iter != active_notification_subscriptions_.end()) { | 
| 322 DCHECK(!ContainsKey(subscriptions_iter->second, characteristic)); | 333 DCHECK(!ContainsKey(subscriptions_iter->second, characteristic)); | 
| 323 } | 334 } | 
| 324 return; | 335 return; | 
| 325 } | 336 } | 
| 326 | 337 | 
| 338 // 3 | |
| 327 // If the object is not in the queue then: | 339 // If the object is not in the queue then: | 
| 328 // 1. The subscription was inactive already: this characteristic | 340 // 1. The subscription was inactive already: this characteristic | 
| 329 // object didn't subscribe to notifications. | 341 // object didn't subscribe to notifications. | 
| 330 // 2. The subscription will become inactive: the characteristic | 342 // 2. The subscription will become inactive: the characteristic | 
| 331 // object that subscribed to notifications is getting destroyed. | 343 // object that subscribed to notifications is getting destroyed. | 
| 332 // 3. The subscription will still be active: there are other | 344 // 3. The subscription will still be active: there are other | 
| 333 // characteristic objects subscribed to notifications. | 345 // characteristic objects subscribed to notifications. | 
| 334 | 346 | 
| 335 if (!HasActiveNotificationSubscription(characteristic_instance_id.utf8())) { | 347 if (!HasActiveNotificationSubscription(characteristic_instance_id.utf8())) { | 
| 336 return; | 348 return; | 
| 337 } | 349 } | 
| 338 | 350 | 
| 339 // For 2 and 3 calling ResolveOrSendStopNotificationsRequest ensures the | 351 // For 2 and 3 calling ResolveOrSendStopNotificationsRequest ensures the | 
| 340 // notification subscription is released. | 352 // notification subscription is released. | 
| 341 // We pass in the characteristic so that ResolveOrSendStopNotificationsRequest | 353 // We pass in the characteristic so that ResolveOrSendStopNotificationsRequest | 
| 342 // can remove the characteristic from ActiveNotificationSubscriptions. | 354 // can remove the characteristic from ActiveNotificationSubscriptions. | 
| 343 ResolveOrSendStopNotificationsRequest(QueueNotificationRequest( | 355 ResolveOrSendStopNotificationsRequest(QueueNotificationRequest( | 
| 344 characteristic_instance_id.utf8(), characteristic, | 356 characteristic_instance_id.utf8(), characteristic, | 
| 345 nullptr /* callbacks */, NotificationsRequestType::STOP)); | 357 nullptr /* callbacks */, NotificationsRequestType::STOP)); | 
| 346 } | 358 } | 
| 347 | 359 | 
| 360 void BluetoothDispatcher::registerCharacteristicObject( | |
| 361 const blink::WebString& characteristic_instance_id, | |
| 362 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
| 363 active_characteristics_.insert( | |
| 364 std::make_pair(characteristic_instance_id.utf8(), characteristic)); | |
| 365 Send(new BluetoothHostMsg_RegisterCharacteristic( | |
| 366 CurrentWorkerId(), characteristic_instance_id.utf8())); | |
| 367 } | |
| 368 | |
| 348 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 369 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 
| 349 delete this; | 370 delete this; | 
| 350 } | 371 } | 
| 351 | 372 | 
| 352 int BluetoothDispatcher::QueueNotificationRequest( | 373 int BluetoothDispatcher::QueueNotificationRequest( | 
| 353 const std::string& characteristic_instance_id, | 374 const std::string& characteristic_instance_id, | 
| 354 blink::WebBluetoothGATTCharacteristic* characteristic, | 375 blink::WebBluetoothGATTCharacteristic* characteristic, | 
| 355 blink::WebBluetoothNotificationsCallbacks* callbacks, | 376 blink::WebBluetoothNotificationsCallbacks* callbacks, | 
| 356 NotificationsRequestType type) { | 377 NotificationsRequestType type) { | 
| 357 int request_id = | 378 int request_id = | 
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 // 1) OnStartNotificationSuccess queues a Stop request because the object | 514 // 1) OnStartNotificationSuccess queues a Stop request because the object | 
| 494 // got destroyed in characteristicObjectRemoved. | 515 // got destroyed in characteristicObjectRemoved. | 
| 495 // 2) The last characteristic object that held this subscription got | 516 // 2) The last characteristic object that held this subscription got | 
| 496 // destroyed in characteristicObjectRemoved. | 517 // destroyed in characteristicObjectRemoved. | 
| 497 if (callbacks != nullptr) { | 518 if (callbacks != nullptr) { | 
| 498 callbacks->onSuccess(); | 519 callbacks->onSuccess(); | 
| 499 } | 520 } | 
| 500 PopNotificationRequestQueueAndProcessNext(request_id); | 521 PopNotificationRequestQueueAndProcessNext(request_id); | 
| 501 } | 522 } | 
| 502 | 523 | 
| 524 void BluetoothDispatcher::UnregisterCharacteristicObject( | |
| 525 const blink::WebString& characteristic_instance_id) { | |
| 526 int removed = | |
| 527 active_characteristics_.erase(characteristic_instance_id.utf8()); | |
| 528 if (removed != 0) { | |
| 529 Send(new BluetoothHostMsg_UnregisterCharacteristic( | |
| 530 CurrentWorkerId(), characteristic_instance_id.utf8())); | |
| 531 } | |
| 532 } | |
| 533 | |
| 503 void BluetoothDispatcher::OnRequestDeviceSuccess( | 534 void BluetoothDispatcher::OnRequestDeviceSuccess( | 
| 504 int thread_id, | 535 int thread_id, | 
| 505 int request_id, | 536 int request_id, | 
| 506 const BluetoothDevice& device) { | 537 const BluetoothDevice& device) { | 
| 507 DCHECK(pending_requests_.Lookup(request_id)) << request_id; | 538 DCHECK(pending_requests_.Lookup(request_id)) << request_id; | 
| 508 | 539 | 
| 509 WebVector<WebString> uuids(device.uuids.size()); | 540 WebVector<WebString> uuids(device.uuids.size()); | 
| 510 for (size_t i = 0; i < device.uuids.size(); ++i) | 541 for (size_t i = 0; i < device.uuids.size(); ++i) | 
| 511 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); | 542 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); | 
| 512 | 543 | 
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 DCHECK( | 740 DCHECK( | 
| 710 !HasActiveNotificationSubscription(request->characteristic_instance_id)); | 741 !HasActiveNotificationSubscription(request->characteristic_instance_id)); | 
| 711 | 742 | 
| 712 if (request->callbacks != nullptr) { | 743 if (request->callbacks != nullptr) { | 
| 713 request->callbacks->onSuccess(); | 744 request->callbacks->onSuccess(); | 
| 714 } | 745 } | 
| 715 | 746 | 
| 716 PopNotificationRequestQueueAndProcessNext(request_id); | 747 PopNotificationRequestQueueAndProcessNext(request_id); | 
| 717 } | 748 } | 
| 718 | 749 | 
| 750 void BluetoothDispatcher::OnCharacteristicValueChanged( | |
| 751 int thread_id, | |
| 752 const std::string& characteristic_instance_id, | |
| 753 const std::vector<uint8_t> new_value) { | |
| 754 auto active_iter = active_characteristics_.find(characteristic_instance_id); | |
| 755 if (active_iter != active_characteristics_.end()) { | |
| 756 active_iter->second->dispatchCharacteristicValueChanged(new_value); | |
| 757 } | |
| 758 } | |
| 759 | |
| 719 } // namespace content | 760 } // namespace content | 
| OLD | NEW |