Chromium Code Reviews| 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" |
| 11 #include "content/child/thread_safe_sender.h" | 11 #include "content/child/thread_safe_sender.h" |
| 12 #include "content/common/bluetooth/bluetooth_messages.h" | 12 #include "content/common/bluetooth/bluetooth_messages.h" |
| 13 #include "device/bluetooth/bluetooth_uuid.h" | 13 #include "device/bluetooth/bluetooth_uuid.h" |
| 14 #include "third_party/WebKit/public/platform/WebPassOwnPtr.h" | 14 #include "third_party/WebKit/public/platform/WebPassOwnPtr.h" |
| 15 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDevic e.h" | 15 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDevic e.h" |
| 16 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError .h" | 16 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError .h" |
| 17 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTC haracteristic.h" | |
| 17 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTC haracteristicInit.h" | 18 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTC haracteristicInit.h" |
| 18 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTR emoteServer.h" | 19 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTR emoteServer.h" |
| 19 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTS ervice.h" | 20 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTS ervice.h" |
| 20 #include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceO ptions.h" | 21 #include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceO ptions.h" |
| 21 | 22 |
| 22 using blink::WebBluetoothConnectGATTCallbacks; | 23 using blink::WebBluetoothConnectGATTCallbacks; |
| 23 using blink::WebBluetoothDevice; | 24 using blink::WebBluetoothDevice; |
| 24 using blink::WebBluetoothError; | 25 using blink::WebBluetoothError; |
| 25 using blink::WebBluetoothGATTCharacteristicInit; | 26 using blink::WebBluetoothGATTCharacteristicInit; |
| 26 using blink::WebBluetoothGATTRemoteServer; | 27 using blink::WebBluetoothGATTRemoteServer; |
| 27 using blink::WebBluetoothGATTService; | 28 using blink::WebBluetoothGATTService; |
| 28 using blink::WebBluetoothReadValueCallbacks; | 29 using blink::WebBluetoothReadValueCallbacks; |
| 29 using blink::WebBluetoothRequestDeviceCallbacks; | 30 using blink::WebBluetoothRequestDeviceCallbacks; |
| 30 using blink::WebBluetoothScanFilter; | 31 using blink::WebBluetoothScanFilter; |
| 31 using blink::WebRequestDeviceOptions; | 32 using blink::WebRequestDeviceOptions; |
| 32 using blink::WebString; | 33 using blink::WebString; |
| 33 using blink::WebVector; | 34 using blink::WebVector; |
| 35 using NotificationsRequestType = | |
| 36 content::BluetoothDispatcher::NotificationsRequestType; | |
| 34 | 37 |
| 35 struct BluetoothPrimaryServiceRequest { | 38 struct BluetoothPrimaryServiceRequest { |
| 36 BluetoothPrimaryServiceRequest( | 39 BluetoothPrimaryServiceRequest( |
| 37 blink::WebString device_instance_id, | 40 blink::WebString device_instance_id, |
| 38 blink::WebString service_uuid, | 41 blink::WebString service_uuid, |
| 39 blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) | 42 blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) |
| 40 : device_instance_id(device_instance_id), | 43 : device_instance_id(device_instance_id), |
| 41 service_uuid(service_uuid), | 44 service_uuid(service_uuid), |
| 42 callbacks(callbacks) {} | 45 callbacks(callbacks) {} |
| 43 ~BluetoothPrimaryServiceRequest() {} | 46 ~BluetoothPrimaryServiceRequest() {} |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 55 : service_instance_id(service_instance_id), | 58 : service_instance_id(service_instance_id), |
| 56 characteristic_uuid(characteristic_uuid), | 59 characteristic_uuid(characteristic_uuid), |
| 57 callbacks(callbacks) {} | 60 callbacks(callbacks) {} |
| 58 ~BluetoothCharacteristicRequest() {} | 61 ~BluetoothCharacteristicRequest() {} |
| 59 | 62 |
| 60 blink::WebString service_instance_id; | 63 blink::WebString service_instance_id; |
| 61 blink::WebString characteristic_uuid; | 64 blink::WebString characteristic_uuid; |
| 62 scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks; | 65 scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks; |
| 63 }; | 66 }; |
| 64 | 67 |
| 68 // Struct that holds a pending Start/StopNotifications request. | |
| 69 struct BluetoothNotificationsRequest { | |
| 70 BluetoothNotificationsRequest( | |
| 71 const std::string characteristic_instance_id, | |
| 72 blink::WebBluetoothGATTCharacteristic* characteristic, | |
| 73 blink::WebBluetoothNotificationsCallbacks* callbacks, | |
| 74 NotificationsRequestType type) | |
| 75 : characteristic_instance_id(characteristic_instance_id), | |
| 76 characteristic(characteristic), | |
| 77 callbacks(callbacks), | |
| 78 type(type) {} | |
| 79 ~BluetoothNotificationsRequest() {} | |
| 80 | |
| 81 const std::string characteristic_instance_id; | |
| 82 // The characteristic object is owned by the execution context on | |
| 83 // the blink side which can destroy the object at any point. Since the | |
| 84 // object implements ActiveDOMObject, the object calls Stop when is getting | |
| 85 // destroyed, which in turn calls characteristicObjectRemoved. | |
| 86 // characteristicObjectRemoved will null any pointers to the object | |
| 87 // and queue a stop notifications request if necessary. | |
| 88 blink::WebBluetoothGATTCharacteristic* characteristic; | |
| 89 scoped_ptr<blink::WebBluetoothNotificationsCallbacks> callbacks; | |
| 90 NotificationsRequestType type; | |
| 91 }; | |
| 92 | |
| 65 namespace content { | 93 namespace content { |
| 66 | 94 |
| 67 namespace { | 95 namespace { |
| 68 | 96 |
| 69 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = | 97 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = |
| 70 LAZY_INSTANCE_INITIALIZER; | 98 LAZY_INSTANCE_INITIALIZER; |
| 71 | 99 |
| 72 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); | 100 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); |
| 73 | 101 |
| 74 int CurrentWorkerId() { | 102 int CurrentWorkerId() { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, | 164 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, |
| 137 OnGetCharacteristicError); | 165 OnGetCharacteristicError); |
| 138 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, | 166 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, |
| 139 OnReadValueSuccess); | 167 OnReadValueSuccess); |
| 140 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, | 168 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, |
| 141 OnReadValueError); | 169 OnReadValueError); |
| 142 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, | 170 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, |
| 143 OnWriteValueSuccess); | 171 OnWriteValueSuccess); |
| 144 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, | 172 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, |
| 145 OnWriteValueError); | 173 OnWriteValueError); |
| 174 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsSuccess, | |
| 175 OnStartNotificationsSuccess) | |
| 176 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsError, | |
| 177 OnStartNotificationsError) | |
| 178 IPC_MESSAGE_HANDLER(BluetoothMsg_StopNotificationsSuccess, | |
| 179 OnStopNotificationsSuccess) | |
| 146 IPC_MESSAGE_UNHANDLED(handled = false) | 180 IPC_MESSAGE_UNHANDLED(handled = false) |
| 147 IPC_END_MESSAGE_MAP() | 181 IPC_END_MESSAGE_MAP() |
| 148 DCHECK(handled) << "Unhandled message:" << msg.type(); | 182 DCHECK(handled) << "Unhandled message:" << msg.type(); |
| 149 } | 183 } |
| 150 | 184 |
| 151 void BluetoothDispatcher::requestDevice( | 185 void BluetoothDispatcher::requestDevice( |
| 152 int frame_routing_id, | 186 int frame_routing_id, |
| 153 const WebRequestDeviceOptions& options, | 187 const WebRequestDeviceOptions& options, |
| 154 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { | 188 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { |
| 155 int request_id = pending_requests_.Add(callbacks); | 189 int request_id = pending_requests_.Add(callbacks); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 void BluetoothDispatcher::writeValue( | 252 void BluetoothDispatcher::writeValue( |
| 219 const blink::WebString& characteristic_instance_id, | 253 const blink::WebString& characteristic_instance_id, |
| 220 const std::vector<uint8_t>& value, | 254 const std::vector<uint8_t>& value, |
| 221 blink::WebBluetoothWriteValueCallbacks* callbacks) { | 255 blink::WebBluetoothWriteValueCallbacks* callbacks) { |
| 222 int request_id = pending_write_value_requests_.Add(callbacks); | 256 int request_id = pending_write_value_requests_.Add(callbacks); |
| 223 | 257 |
| 224 Send(new BluetoothHostMsg_WriteValue( | 258 Send(new BluetoothHostMsg_WriteValue( |
| 225 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); | 259 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); |
| 226 } | 260 } |
| 227 | 261 |
| 262 void BluetoothDispatcher::startNotifications( | |
| 263 const blink::WebString& characteristic_instance_id, | |
| 264 blink::WebBluetoothGATTCharacteristic* characteristic, | |
| 265 blink::WebBluetoothNotificationsCallbacks* callbacks) { | |
| 266 int request_id = QueueNotificationRequest(characteristic_instance_id.utf8(), | |
| 267 characteristic, callbacks, | |
| 268 NotificationsRequestType::START); | |
| 269 | |
| 270 // The Notification subscription's state can change after a request | |
| 271 // finishes. To avoid resolving with a soon-to-be-invalid state we queue | |
| 272 // requests. | |
| 273 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
| 274 return; | |
| 275 } | |
| 276 | |
| 277 processStartNotificationsRequest(request_id); | |
| 278 } | |
| 279 | |
| 280 void BluetoothDispatcher::stopNotifications( | |
| 281 const blink::WebString& characteristic_instance_id, | |
| 282 blink::WebBluetoothGATTCharacteristic* characteristic, | |
| 283 blink::WebBluetoothNotificationsCallbacks* callbacks) { | |
| 284 int request_id = QueueNotificationRequest(characteristic_instance_id.utf8(), | |
| 285 characteristic, callbacks, | |
| 286 NotificationsRequestType::STOP); | |
| 287 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
| 288 return; | |
| 289 } | |
| 290 | |
| 291 processStopNotificationsRequest(request_id); | |
| 292 } | |
| 293 | |
| 294 void BluetoothDispatcher::characteristicObjectRemoved( | |
| 295 const blink::WebString& characteristic_instance_id, | |
| 296 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
| 297 // If there is a notification request pending then there are two posibilities: | |
| 298 // 1. The subscription is going to be active. If this is the case, | |
| 299 // we null the characteristic object. startNotificationsSuccess will take | |
| 300 // care of stopping the notifications. | |
| 301 // 2. The subscription is going to be inactive. If this is the case, we | |
| 302 // don't need to to anything since the notification is stopped already. | |
| 303 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
| 304 for (IDMap<BluetoothNotificationsRequest, IDMapOwnPointer>::iterator iter( | |
| 305 &pending_notifications_requests_); | |
| 306 !iter.IsAtEnd(); iter.Advance()) { | |
| 307 iter.GetCurrentValue()->characteristic = nullptr; | |
| 308 } | |
| 309 return; | |
| 310 } | |
| 311 | |
| 312 // If there are no notification requests pending then there are three | |
| 313 // possibilities after removing this characteristic: | |
| 314 // 1. The subscription was inactive already. | |
| 315 // 2. The subscription will become inactive. | |
|
scheib
2015/10/01 22:05:23
Case 2 is only if another frame holds the subscrip
ortuno
2015/10/03 04:03:03
Not sure I follow: Case 2 happens when this is the
scheib
2015/10/04 01:35:58
Add detail to the comments somehow explaining case
ortuno
2015/10/06 02:38:43
Done.
| |
| 316 // 3. The subscription will still be active. | |
| 317 | |
| 318 if (!HasActiveNotificationSubscription(characteristic_instance_id.utf8())) { | |
| 319 return; | |
| 320 } | |
| 321 | |
| 322 // For 2 and 3. We simply call processStopNotificationsRequest which will take | |
| 323 // care of stopping the notifications if the subscription becomes inactive. | |
|
scheib
2015/10/01 22:05:23
Perhaps:
For 3 calling processStopNotificationsReq
ortuno
2015/10/03 04:03:03
Done.
| |
| 324 processStopNotificationsRequest(QueueNotificationRequest( | |
| 325 characteristic_instance_id.utf8(), characteristic, | |
|
scheib
2015/10/01 22:05:23
characteristic should be nullptr
ortuno
2015/10/03 04:03:03
We still need to remove the characteristic from th
scheib
2015/10/04 01:35:58
OK, yeah, this is complicated enough that's not ob
ortuno
2015/10/06 02:38:43
Done.
| |
| 326 nullptr /* callbacks */, NotificationsRequestType::STOP)); | |
| 327 } | |
| 328 | |
| 228 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 329 void BluetoothDispatcher::WillStopCurrentWorkerThread() { |
| 229 delete this; | 330 delete this; |
| 230 } | 331 } |
| 231 | 332 |
| 333 int BluetoothDispatcher::QueueNotificationRequest( | |
| 334 const std::string& characteristic_instance_id, | |
| 335 blink::WebBluetoothGATTCharacteristic* characteristic, | |
| 336 blink::WebBluetoothNotificationsCallbacks* callbacks, | |
| 337 NotificationsRequestType type) { | |
| 338 int request_id = | |
| 339 pending_notifications_requests_.Add(new BluetoothNotificationsRequest( | |
| 340 characteristic_instance_id, characteristic, callbacks, type)); | |
| 341 queued_notification_requests_[characteristic_instance_id].push(request_id); | |
| 342 | |
| 343 return request_id; | |
| 344 } | |
| 345 | |
| 346 void BluetoothDispatcher::ProcessQueuedNotificationRequests(int request_id) { | |
| 347 BluetoothNotificationsRequest* old_request = | |
| 348 pending_notifications_requests_.Lookup(request_id); | |
| 349 | |
| 350 auto queue_iter = queued_notification_requests_.find( | |
| 351 old_request->characteristic_instance_id); | |
| 352 | |
| 353 CHECK(queue_iter != queued_notification_requests_.end()); | |
| 354 | |
| 355 std::queue<int>& request_queue = queue_iter->second; | |
| 356 | |
| 357 DCHECK(request_queue.front() == request_id); | |
| 358 | |
| 359 // Remove old request and clean map if necessary. | |
| 360 request_queue.pop(); | |
| 361 pending_notifications_requests_.Remove(request_id); | |
| 362 if (request_queue.empty()) { | |
| 363 queued_notification_requests_.erase(queue_iter); | |
| 364 return; | |
| 365 } | |
| 366 | |
| 367 int next_request_id = request_queue.front(); | |
| 368 BluetoothNotificationsRequest* next_request = | |
| 369 pending_notifications_requests_.Lookup(next_request_id); | |
| 370 | |
| 371 switch (next_request->type) { | |
| 372 case NotificationsRequestType::START: | |
| 373 processStartNotificationsRequest(next_request_id); | |
| 374 return; | |
| 375 case NotificationsRequestType::STOP: | |
| 376 processStopNotificationsRequest(next_request_id); | |
| 377 return; | |
| 378 } | |
| 379 } | |
| 380 | |
| 381 bool BluetoothDispatcher::PendingNotificationRequest( | |
| 382 const std::string& characteristic_instance_id) { | |
| 383 return queued_notification_requests_.find(characteristic_instance_id) != | |
| 384 queued_notification_requests_.end() && | |
| 385 (queued_notification_requests_[characteristic_instance_id].size() > 1); | |
| 386 } | |
| 387 | |
| 388 bool BluetoothDispatcher::HasActiveNotificationSubscription( | |
| 389 const std::string& characteristic_instance_id) { | |
| 390 return ContainsKey(active_notification_subscriptions_, | |
| 391 characteristic_instance_id); | |
| 392 } | |
| 393 | |
| 394 void BluetoothDispatcher::AddToActiveNotificationSubscriptions( | |
| 395 const std::string& characteristic_instance_id, | |
| 396 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
| 397 active_notification_subscriptions_[characteristic_instance_id].insert( | |
| 398 characteristic); | |
| 399 } | |
| 400 | |
| 401 bool BluetoothDispatcher::RemoveFromActiveNotificationSubscriptions( | |
| 402 const std::string& characteristic_instance_id, | |
| 403 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
| 404 auto active_map = | |
| 405 active_notification_subscriptions_.find(characteristic_instance_id); | |
| 406 | |
| 407 if (active_map == active_notification_subscriptions_.end()) { | |
| 408 return false; | |
| 409 } | |
| 410 | |
| 411 active_map->second.erase(characteristic); | |
| 412 | |
| 413 if (active_map->second.empty()) { | |
| 414 active_notification_subscriptions_.erase(active_map); | |
| 415 DCHECK(!HasActiveNotificationSubscription(characteristic_instance_id)); | |
| 416 return true; | |
| 417 } | |
| 418 return false; | |
| 419 } | |
| 420 | |
| 421 void BluetoothDispatcher::processStartNotificationsRequest(int request_id) { | |
| 422 BluetoothNotificationsRequest* request = | |
| 423 pending_notifications_requests_.Lookup(request_id); | |
| 424 const std::string& characteristic_instance_id = | |
| 425 request->characteristic_instance_id; | |
| 426 blink::WebBluetoothGATTCharacteristic* characteristic = | |
|
scheib
2015/10/01 22:05:23
characteristic may be nullptr due to characteristi
ortuno
2015/10/03 04:03:03
That's tricky and seems like a question for Jeffre
scheib
2015/10/04 01:35:58
Can wait for J if you like, but below on Start suc
ortuno
2015/10/06 02:38:43
Chatted offline. We will send the request for now
| |
| 427 request->characteristic; | |
| 428 blink::WebBluetoothNotificationsCallbacks* callbacks = | |
| 429 request->callbacks.get(); | |
| 430 | |
| 431 // If an object is already subscribed to notifications from the characteristic | |
| 432 // no need to send an IPC again. | |
| 433 if (HasActiveNotificationSubscription(characteristic_instance_id)) { | |
| 434 AddToActiveNotificationSubscriptions(characteristic_instance_id, | |
| 435 characteristic); | |
| 436 callbacks->onSuccess(); | |
| 437 | |
| 438 ProcessQueuedNotificationRequests(request_id); | |
| 439 return; | |
| 440 } | |
| 441 Send(new BluetoothHostMsg_StartNotifications(CurrentWorkerId(), request_id, | |
| 442 characteristic_instance_id)); | |
| 443 } | |
| 444 | |
| 445 void BluetoothDispatcher::processStopNotificationsRequest(int request_id) { | |
| 446 // The Notification subscription's state can change after a request | |
| 447 // finishes. To avoid resolving with a soon-to-be-invalid state we queue | |
| 448 // requests. | |
| 449 BluetoothNotificationsRequest* request = | |
| 450 pending_notifications_requests_.Lookup(request_id); | |
| 451 const std::string& characteristic_instance_id = | |
| 452 request->characteristic_instance_id; | |
| 453 blink::WebBluetoothGATTCharacteristic* characteristic = | |
| 454 request->characteristic; | |
| 455 blink::WebBluetoothNotificationsCallbacks* callbacks = | |
| 456 request->callbacks.get(); | |
| 457 | |
| 458 // If removing turns the subscription inactive then stop. | |
| 459 if (RemoveFromActiveNotificationSubscriptions(characteristic_instance_id, | |
| 460 characteristic)) { | |
|
scheib
2015/10/01 22:05:23
May be removing from here with characteristic == n
ortuno
2015/10/03 04:03:03
That's why we pass the characteristic and not null
scheib
2015/10/04 01:35:58
We do? I don't see WebBluetoothCharacteristics acc
ortuno
2015/10/06 02:38:43
It's not used yet. WebBluetoothCharacteristics is
| |
| 461 Send(new BluetoothHostMsg_StopNotifications(CurrentWorkerId(), request_id, | |
| 462 characteristic_instance_id)); | |
| 463 return; | |
| 464 } | |
| 465 // An object is destroyed 1) during a start request or 2) after a start | |
|
scheib
2015/10/01 22:05:23
Reform comment more like this for readability:
Po
ortuno
2015/10/03 04:03:03
Done.
scheib
2015/10/04 01:35:58
I think you can delete the first 7 comment lines f
ortuno
2015/10/06 02:38:43
Done.
| |
| 466 // request. If 1), then OnStartNotificationsSuccess will queue a stop with | |
| 467 // callback = nullptr and characteristic = nullptr which will eventually call | |
| 468 // processStopNotificationsRequest. If 2), characteristic needs to be removed | |
| 469 // from active_notifications_subscriptions so onCharacteristicObjectRemoved | |
| 470 // will call processStopNotification with callback = nullptr only. | |
| 471 if (callbacks != nullptr) { | |
| 472 callbacks->onSuccess(); | |
| 473 } | |
| 474 ProcessQueuedNotificationRequests(request_id); | |
| 475 } | |
| 476 | |
| 232 void BluetoothDispatcher::OnRequestDeviceSuccess( | 477 void BluetoothDispatcher::OnRequestDeviceSuccess( |
| 233 int thread_id, | 478 int thread_id, |
| 234 int request_id, | 479 int request_id, |
| 235 const BluetoothDevice& device) { | 480 const BluetoothDevice& device) { |
| 236 DCHECK(pending_requests_.Lookup(request_id)) << request_id; | 481 DCHECK(pending_requests_.Lookup(request_id)) << request_id; |
| 237 | 482 |
| 238 WebVector<WebString> uuids(device.uuids.size()); | 483 WebVector<WebString> uuids(device.uuids.size()); |
| 239 for (size_t i = 0; i < device.uuids.size(); ++i) | 484 for (size_t i = 0; i < device.uuids.size(); ++i) |
| 240 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); | 485 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); |
| 241 | 486 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 int request_id, | 624 int request_id, |
| 380 WebBluetoothError error) { | 625 WebBluetoothError error) { |
| 381 DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id; | 626 DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id; |
| 382 | 627 |
| 383 pending_write_value_requests_.Lookup(request_id) | 628 pending_write_value_requests_.Lookup(request_id) |
| 384 ->onError(WebBluetoothError(error)); | 629 ->onError(WebBluetoothError(error)); |
| 385 | 630 |
| 386 pending_write_value_requests_.Remove(request_id); | 631 pending_write_value_requests_.Remove(request_id); |
| 387 } | 632 } |
| 388 | 633 |
| 634 void BluetoothDispatcher::OnStartNotificationsSuccess(int thread_id, | |
| 635 int request_id) { | |
| 636 DCHECK(pending_notifications_requests_.Lookup(request_id)) << request_id; | |
| 637 | |
| 638 BluetoothNotificationsRequest* request = | |
| 639 pending_notifications_requests_.Lookup(request_id); | |
| 640 | |
| 641 DCHECK(queued_notification_requests_[request->characteristic_instance_id] | |
| 642 .front() == request_id); | |
| 643 | |
| 644 // We only send an IPC for inactive notifications. | |
| 645 DCHECK( | |
| 646 !HasActiveNotificationSubscription(request->characteristic_instance_id)); | |
| 647 | |
| 648 AddToActiveNotificationSubscriptions(request->characteristic_instance_id, | |
| 649 request->characteristic); | |
| 650 | |
| 651 // The object requesting the notification could have been destroyed | |
| 652 // while waiting for the subscription. characteristicRemoved | |
| 653 // nulls the characteristic when the corresponding js object gets destroyed. | |
| 654 // Since there could be other characteristics waiting to subscribe, we queue | |
|
scheib
2015/10/01 22:05:23
I understand sending a Stop when the object is des
ortuno
2015/10/03 04:03:03
// Frame 1
char.startNotifications()
// char gets
scheib
2015/10/04 01:35:58
Improve comments in code to address the uncertaint
ortuno
2015/10/06 02:38:43
Done.
| |
| 655 // a stop. | |
| 656 if (request->characteristic == nullptr) { | |
| 657 QueueNotificationRequest( | |
| 658 request->characteristic_instance_id, nullptr /* characteristic */, | |
| 659 nullptr /* callbacks */, NotificationsRequestType::STOP); | |
| 660 } | |
| 661 | |
| 662 request->callbacks->onSuccess(); | |
| 663 | |
| 664 ProcessQueuedNotificationRequests(request_id); | |
| 665 } | |
| 666 | |
| 667 void BluetoothDispatcher::OnStartNotificationsError(int thread_id, | |
| 668 int request_id, | |
| 669 WebBluetoothError error) { | |
| 670 DCHECK(pending_notifications_requests_.Lookup(request_id)) << request_id; | |
| 671 | |
| 672 BluetoothNotificationsRequest* request = | |
| 673 pending_notifications_requests_.Lookup(request_id); | |
| 674 | |
| 675 DCHECK(queued_notification_requests_[request->characteristic_instance_id] | |
| 676 .front() == request_id); | |
| 677 | |
| 678 // We only send an IPC for inactive notifications. | |
| 679 DCHECK( | |
| 680 !HasActiveNotificationSubscription(request->characteristic_instance_id)); | |
| 681 | |
| 682 request->callbacks->onError(error); | |
| 683 | |
| 684 ProcessQueuedNotificationRequests(request_id); | |
| 685 } | |
| 686 | |
| 687 void BluetoothDispatcher::OnStopNotificationsSuccess(int thread_id, | |
| 688 int request_id) { | |
| 689 DCHECK(pending_notifications_requests_.Lookup(request_id)) << request_id; | |
| 690 | |
| 691 BluetoothNotificationsRequest* request = | |
| 692 pending_notifications_requests_.Lookup(request_id); | |
| 693 | |
| 694 DCHECK(queued_notification_requests_[request->characteristic_instance_id] | |
| 695 .front() == request_id); | |
| 696 | |
| 697 // We only send an IPC for inactive notifications. | |
| 698 DCHECK( | |
| 699 !HasActiveNotificationSubscription(request->characteristic_instance_id)); | |
| 700 | |
| 701 if (request->callbacks != nullptr) { | |
| 702 request->callbacks->onSuccess(); | |
| 703 } | |
| 704 | |
| 705 ProcessQueuedNotificationRequests(request_id); | |
| 706 } | |
| 707 | |
| 389 } // namespace content | 708 } // namespace content |
| OLD | NEW |