| 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 | 
|  | 307   // there are no characteristic objects that have listeners attached. | 
|  | 308   // https://crbug.com/541388 | 
|  | 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   // TODO(ortuno): After the Object manager is implemented, there will | 
|  | 364   // only be one object per characteristic. But for now we remove | 
|  | 365   // the previous object. | 
|  | 366   // https://crbug.com/495270 | 
|  | 367   active_characteristics_.erase(characteristic_instance_id.utf8()); | 
|  | 368 | 
|  | 369   active_characteristics_.insert( | 
|  | 370       std::make_pair(characteristic_instance_id.utf8(), characteristic)); | 
|  | 371 | 
|  | 372   Send(new BluetoothHostMsg_RegisterCharacteristic( | 
|  | 373       CurrentWorkerId(), characteristic_instance_id.utf8())); | 
|  | 374 } | 
|  | 375 | 
| 348 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 376 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 
| 349   delete this; | 377   delete this; | 
| 350 } | 378 } | 
| 351 | 379 | 
| 352 int BluetoothDispatcher::QueueNotificationRequest( | 380 int BluetoothDispatcher::QueueNotificationRequest( | 
| 353     const std::string& characteristic_instance_id, | 381     const std::string& characteristic_instance_id, | 
| 354     blink::WebBluetoothGATTCharacteristic* characteristic, | 382     blink::WebBluetoothGATTCharacteristic* characteristic, | 
| 355     blink::WebBluetoothNotificationsCallbacks* callbacks, | 383     blink::WebBluetoothNotificationsCallbacks* callbacks, | 
| 356     NotificationsRequestType type) { | 384     NotificationsRequestType type) { | 
| 357   int request_id = | 385   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 | 521   //   1) OnStartNotificationSuccess queues a Stop request because the object | 
| 494   //      got destroyed in characteristicObjectRemoved. | 522   //      got destroyed in characteristicObjectRemoved. | 
| 495   //   2) The last characteristic object that held this subscription got | 523   //   2) The last characteristic object that held this subscription got | 
| 496   //      destroyed in characteristicObjectRemoved. | 524   //      destroyed in characteristicObjectRemoved. | 
| 497   if (callbacks != nullptr) { | 525   if (callbacks != nullptr) { | 
| 498     callbacks->onSuccess(); | 526     callbacks->onSuccess(); | 
| 499   } | 527   } | 
| 500   PopNotificationRequestQueueAndProcessNext(request_id); | 528   PopNotificationRequestQueueAndProcessNext(request_id); | 
| 501 } | 529 } | 
| 502 | 530 | 
|  | 531 void BluetoothDispatcher::UnregisterCharacteristicObject( | 
|  | 532     const blink::WebString& characteristic_instance_id) { | 
|  | 533   int removed = | 
|  | 534       active_characteristics_.erase(characteristic_instance_id.utf8()); | 
|  | 535   if (removed != 0) { | 
|  | 536     Send(new BluetoothHostMsg_UnregisterCharacteristic( | 
|  | 537         CurrentWorkerId(), characteristic_instance_id.utf8())); | 
|  | 538   } | 
|  | 539 } | 
|  | 540 | 
| 503 void BluetoothDispatcher::OnRequestDeviceSuccess( | 541 void BluetoothDispatcher::OnRequestDeviceSuccess( | 
| 504     int thread_id, | 542     int thread_id, | 
| 505     int request_id, | 543     int request_id, | 
| 506     const BluetoothDevice& device) { | 544     const BluetoothDevice& device) { | 
| 507   DCHECK(pending_requests_.Lookup(request_id)) << request_id; | 545   DCHECK(pending_requests_.Lookup(request_id)) << request_id; | 
| 508 | 546 | 
| 509   WebVector<WebString> uuids(device.uuids.size()); | 547   WebVector<WebString> uuids(device.uuids.size()); | 
| 510   for (size_t i = 0; i < device.uuids.size(); ++i) | 548   for (size_t i = 0; i < device.uuids.size(); ++i) | 
| 511     uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); | 549     uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); | 
| 512 | 550 | 
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 709   DCHECK( | 747   DCHECK( | 
| 710       !HasActiveNotificationSubscription(request->characteristic_instance_id)); | 748       !HasActiveNotificationSubscription(request->characteristic_instance_id)); | 
| 711 | 749 | 
| 712   if (request->callbacks != nullptr) { | 750   if (request->callbacks != nullptr) { | 
| 713     request->callbacks->onSuccess(); | 751     request->callbacks->onSuccess(); | 
| 714   } | 752   } | 
| 715 | 753 | 
| 716   PopNotificationRequestQueueAndProcessNext(request_id); | 754   PopNotificationRequestQueueAndProcessNext(request_id); | 
| 717 } | 755 } | 
| 718 | 756 | 
|  | 757 void BluetoothDispatcher::OnCharacteristicValueChanged( | 
|  | 758     int thread_id, | 
|  | 759     const std::string& characteristic_instance_id, | 
|  | 760     const std::vector<uint8_t> new_value) { | 
|  | 761   auto active_iter = active_characteristics_.find(characteristic_instance_id); | 
|  | 762   if (active_iter != active_characteristics_.end()) { | 
|  | 763     active_iter->second->dispatchCharacteristicValueChanged(new_value); | 
|  | 764   } | 
|  | 765 } | 
|  | 766 | 
| 719 }  // namespace content | 767 }  // namespace content | 
| OLD | NEW | 
|---|