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