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 BluetoothNotificationsRequest { | |
Jeffrey Yasskin
2015/09/25 23:03:19
Maybe "BluetoothNotificationStateChangeRequest"? O
ortuno
2015/09/29 22:47:36
Done.
| |
69 BluetoothNotificationsRequest( | |
70 const std::string characteristic_instance_id, | |
71 blink::WebBluetoothGATTCharacteristic* characteristic, | |
72 blink::WebBluetoothNotificationsCallbacks* callbacks, | |
73 NotificationsRequestType type) | |
74 : characteristic_instance_id(characteristic_instance_id), | |
75 characteristic(characteristic), | |
76 callbacks(callbacks), | |
77 type(type) {} | |
78 ~BluetoothNotificationsRequest() {} | |
79 | |
80 const std::string characteristic_instance_id; | |
81 // Note that the characteristic object is owned by the execution context on | |
82 // the blink side which can destroy the object at any point. Since the | |
83 // object implements ActiveDOMObject we do get notify when it's being | |
Jeffrey Yasskin
2015/09/25 23:03:19
Instead of "we get notified", can you mention the
ortuno
2015/09/29 22:47:36
Done.
| |
84 // destroyed, so we can remove any references to it. | |
85 blink::WebBluetoothGATTCharacteristic* characteristic; | |
86 scoped_ptr<blink::WebBluetoothNotificationsCallbacks> callbacks; | |
87 NotificationsRequestType type; | |
88 }; | |
89 | |
65 namespace content { | 90 namespace content { |
66 | 91 |
67 namespace { | 92 namespace { |
68 | 93 |
69 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = | 94 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = |
70 LAZY_INSTANCE_INITIALIZER; | 95 LAZY_INSTANCE_INITIALIZER; |
71 | 96 |
72 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); | 97 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); |
73 | 98 |
74 int CurrentWorkerId() { | 99 int CurrentWorkerId() { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, | 161 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, |
137 OnGetCharacteristicError); | 162 OnGetCharacteristicError); |
138 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, | 163 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, |
139 OnReadValueSuccess); | 164 OnReadValueSuccess); |
140 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, | 165 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, |
141 OnReadValueError); | 166 OnReadValueError); |
142 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, | 167 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, |
143 OnWriteValueSuccess); | 168 OnWriteValueSuccess); |
144 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, | 169 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, |
145 OnWriteValueError); | 170 OnWriteValueError); |
171 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsSuccess, | |
172 OnStartNotificationsSuccess) | |
173 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsError, | |
174 OnStartNotificationsError) | |
175 IPC_MESSAGE_HANDLER(BluetoothMsg_StopNotificationsSuccess, | |
176 OnStopNotificationsSuccess) | |
146 IPC_MESSAGE_UNHANDLED(handled = false) | 177 IPC_MESSAGE_UNHANDLED(handled = false) |
147 IPC_END_MESSAGE_MAP() | 178 IPC_END_MESSAGE_MAP() |
148 DCHECK(handled) << "Unhandled message:" << msg.type(); | 179 DCHECK(handled) << "Unhandled message:" << msg.type(); |
149 } | 180 } |
150 | 181 |
151 void BluetoothDispatcher::requestDevice( | 182 void BluetoothDispatcher::requestDevice( |
152 int frame_routing_id, | 183 int frame_routing_id, |
153 const WebRequestDeviceOptions& options, | 184 const WebRequestDeviceOptions& options, |
154 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { | 185 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { |
155 int request_id = pending_requests_.Add(callbacks); | 186 int request_id = pending_requests_.Add(callbacks); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 void BluetoothDispatcher::writeValue( | 249 void BluetoothDispatcher::writeValue( |
219 const blink::WebString& characteristic_instance_id, | 250 const blink::WebString& characteristic_instance_id, |
220 const std::vector<uint8_t>& value, | 251 const std::vector<uint8_t>& value, |
221 blink::WebBluetoothWriteValueCallbacks* callbacks) { | 252 blink::WebBluetoothWriteValueCallbacks* callbacks) { |
222 int request_id = pending_write_value_requests_.Add(callbacks); | 253 int request_id = pending_write_value_requests_.Add(callbacks); |
223 | 254 |
224 Send(new BluetoothHostMsg_WriteValue( | 255 Send(new BluetoothHostMsg_WriteValue( |
225 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); | 256 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); |
226 } | 257 } |
227 | 258 |
259 void BluetoothDispatcher::startNotifications( | |
260 const blink::WebString& characteristic_instance_id, | |
261 blink::WebBluetoothGATTCharacteristic* characteristic, | |
262 blink::WebBluetoothNotificationsCallbacks* callbacks) { | |
263 int request_id = QueueNotificationRequest(characteristic_instance_id.utf8(), | |
264 characteristic, callbacks, | |
265 NotificationsRequestType::START); | |
266 | |
267 // The Notification subscription's state can change after a request | |
268 // finishes. To avoid resolving with a soon-to-be-invalid state we queue | |
269 // requests. | |
270 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
271 return; | |
272 } | |
273 | |
274 processStartNotificationsRequest(request_id); | |
275 } | |
276 | |
277 void BluetoothDispatcher::stopNotifications( | |
278 const blink::WebString& characteristic_instance_id, | |
279 blink::WebBluetoothGATTCharacteristic* characteristic, | |
280 blink::WebBluetoothNotificationsCallbacks* callbacks) { | |
281 int request_id = QueueNotificationRequest(characteristic_instance_id.utf8(), | |
282 characteristic, callbacks, | |
283 NotificationsRequestType::STOP); | |
284 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
285 return; | |
286 } | |
287 | |
288 processStopNotificationsRequest(request_id); | |
289 } | |
290 | |
291 void BluetoothDispatcher::characteristicObjectRemoved( | |
292 const blink::WebString& characteristic_instance_id, | |
293 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
294 // If there is a notification request pending then there are two posibilities: | |
295 // 1. The subscription is going to be active. If this is the case, | |
296 // we null the characteristic object. startNotificationsSuccess will take | |
297 // care of stopping the notifications. | |
298 // 2. The subscription is going to be inactive. If this is the case, we | |
299 // don't need to to anything since the notification is stopped already. | |
300 if (PendingNotificationRequest(characteristic_instance_id.utf8())) { | |
301 for (IDMap<BluetoothNotificationsRequest, IDMapOwnPointer>::iterator iter( | |
302 &pending_notifications_requests_); | |
303 !iter.IsAtEnd(); iter.Advance()) { | |
304 iter.GetCurrentValue()->characteristic = nullptr; | |
305 } | |
306 return; | |
307 } | |
308 | |
309 // If there are no notification requests pending then there are three | |
310 // possibilities after removing this characteristic: | |
311 // 1. The subscription was innactive already. | |
Jeffrey Yasskin
2015/09/25 23:03:19
sp: innactive, and on the next line
ortuno
2015/09/29 22:47:36
Done.
| |
312 // 2. The subscription will become innactive. | |
313 // 3. The subscription will still be active. | |
314 | |
315 if (!HasActiveNotificationSubscription(characteristic_instance_id.utf8())) { | |
316 return; | |
317 } | |
318 | |
319 // For 2 and 3. We simply call processStopNotificationsRequest which will take | |
320 // care of stopping the notifications if the subscription becomes inactive. | |
321 processStopNotificationsRequest(QueueNotificationRequest( | |
322 characteristic_instance_id.utf8(), characteristic, | |
323 nullptr /* callbacks */, NotificationsRequestType::STOP)); | |
324 } | |
325 | |
228 void BluetoothDispatcher::WillStopCurrentWorkerThread() { | 326 void BluetoothDispatcher::WillStopCurrentWorkerThread() { |
229 delete this; | 327 delete this; |
230 } | 328 } |
231 | 329 |
330 int BluetoothDispatcher::QueueNotificationRequest( | |
331 const std::string& characteristic_instance_id, | |
332 blink::WebBluetoothGATTCharacteristic* characteristic, | |
333 blink::WebBluetoothNotificationsCallbacks* callbacks, | |
334 NotificationsRequestType type) { | |
335 int request_id; | |
336 switch (type) { | |
337 case NotificationsRequestType::START: | |
338 request_id = | |
339 pending_notifications_requests_.Add(new BluetoothNotificationsRequest( | |
Jeffrey Yasskin
2015/09/25 23:03:19
It looks like you don't actually need the switch h
ortuno
2015/09/29 22:47:36
Done.
| |
340 characteristic_instance_id, characteristic, callbacks, type)); | |
341 break; | |
342 case NotificationsRequestType::STOP: | |
343 request_id = | |
344 pending_notifications_requests_.Add(new BluetoothNotificationsRequest( | |
345 characteristic_instance_id, characteristic, callbacks, type)); | |
346 break; | |
347 } | |
348 queued_notification_requests_[characteristic_instance_id].push(request_id); | |
349 | |
350 return request_id; | |
351 } | |
352 | |
353 void BluetoothDispatcher::ProcessQueuedNotificationRequests(int request_id) { | |
354 BluetoothNotificationsRequest* old_request = | |
355 pending_notifications_requests_.Lookup(request_id); | |
356 | |
357 auto queue_iter = queued_notification_requests_.find( | |
Jeffrey Yasskin
2015/09/25 23:03:19
Also CHECK(queue_iter != queued_notification_reque
ortuno
2015/09/29 22:47:36
Done.
| |
358 old_request->characteristic_instance_id); | |
359 | |
360 DCHECK(queue_iter->second.front() == request_id); | |
Jeffrey Yasskin
2015/09/25 23:03:20
Alias std::queue<int>& request_queue = queue_iter-
ortuno
2015/09/29 22:47:36
Done.
| |
361 | |
362 // Remove old request and clean map if necessary. | |
363 queue_iter->second.pop(); | |
364 pending_notifications_requests_.Remove(request_id); | |
365 if (queue_iter->second.empty()) { | |
366 queued_notification_requests_.erase(queue_iter); | |
367 return; | |
368 } | |
369 | |
370 int next_request_id = queue_iter->second.front(); | |
371 BluetoothNotificationsRequest* next_request = | |
372 pending_notifications_requests_.Lookup(next_request_id); | |
373 | |
374 switch (next_request->type) { | |
375 case NotificationsRequestType::START: | |
376 processStartNotificationsRequest(next_request_id); | |
377 return; | |
378 case NotificationsRequestType::STOP: | |
379 processStopNotificationsRequest(next_request_id); | |
380 return; | |
381 } | |
382 } | |
383 | |
384 bool BluetoothDispatcher::PendingNotificationRequest( | |
385 const std::string& characteristic_instance_id) { | |
386 return queued_notification_requests_.find(characteristic_instance_id) != | |
387 queued_notification_requests_.end() && | |
388 (queued_notification_requests_[characteristic_instance_id].size() > 1); | |
389 } | |
390 | |
391 bool BluetoothDispatcher::HasActiveNotificationSubscription( | |
392 const std::string& characteristic_instance_id) { | |
393 return active_notification_subscriptions_.find(characteristic_instance_id) != | |
Jeffrey Yasskin
2015/09/25 23:03:19
You can use ContainsKey() for this (https://code.g
ortuno
2015/09/29 22:47:36
Done.
| |
394 active_notification_subscriptions_.end(); | |
395 } | |
396 | |
397 void BluetoothDispatcher::AddToActiveNotificationSubscriptions( | |
398 const std::string& characteristic_instance_id, | |
399 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
400 active_notification_subscriptions_[characteristic_instance_id].insert( | |
401 characteristic); | |
402 } | |
403 | |
404 bool BluetoothDispatcher::RemoveFromActiveNotificationSubscriptions( | |
405 const std::string& characteristic_instance_id, | |
406 blink::WebBluetoothGATTCharacteristic* characteristic) { | |
407 auto active_map = | |
408 active_notification_subscriptions_.find(characteristic_instance_id); | |
409 | |
410 if (active_map == active_notification_subscriptions_.end()) { | |
411 return false; | |
412 } | |
413 | |
414 active_map->second.erase(characteristic); | |
415 | |
416 if (active_map->second.empty()) { | |
417 active_notification_subscriptions_.erase(active_map); | |
418 DCHECK(!HasActiveNotificationSubscription(characteristic_instance_id)); | |
419 return true; | |
420 } | |
421 return false; | |
422 } | |
423 | |
424 void BluetoothDispatcher::processStartNotificationsRequest(int request_id) { | |
425 BluetoothNotificationsRequest* request = | |
426 pending_notifications_requests_.Lookup(request_id); | |
427 const std::string& characteristic_instance_id = | |
428 request->characteristic_instance_id; | |
429 blink::WebBluetoothGATTCharacteristic* characteristic = | |
430 request->characteristic; | |
431 blink::WebBluetoothNotificationsCallbacks* callbacks = | |
432 request->callbacks.get(); | |
433 | |
434 // If an object is already subscribed to notifications from the characteristic | |
435 // no need to send an IPC again. | |
436 if (HasActiveNotificationSubscription(characteristic_instance_id)) { | |
437 AddToActiveNotificationSubscriptions(characteristic_instance_id, | |
438 characteristic); | |
439 callbacks->onSuccess(); | |
440 | |
441 ProcessQueuedNotificationRequests(request_id); | |
442 return; | |
443 } | |
444 Send(new BluetoothHostMsg_StartNotifications(CurrentWorkerId(), request_id, | |
445 characteristic_instance_id)); | |
446 } | |
447 | |
448 void BluetoothDispatcher::processStopNotificationsRequest(int request_id) { | |
449 // The Notification subscription's state can change after a request | |
450 // finishes. To avoid resolving with a soon-to-be-invalid state we queue | |
451 // requests. | |
452 BluetoothNotificationsRequest* request = | |
453 pending_notifications_requests_.Lookup(request_id); | |
454 const std::string& characteristic_instance_id = | |
455 request->characteristic_instance_id; | |
456 blink::WebBluetoothGATTCharacteristic* characteristic = | |
457 request->characteristic; | |
458 blink::WebBluetoothNotificationsCallbacks* callbacks = | |
459 request->callbacks.get(); | |
460 | |
461 // If removing turns the subscription inactive then stop. | |
462 if (RemoveFromActiveNotificationSubscriptions(characteristic_instance_id, | |
463 characteristic)) { | |
464 Send(new BluetoothHostMsg_StopNotifications(CurrentWorkerId(), request_id, | |
465 characteristic_instance_id)); | |
466 return; | |
467 } | |
468 // If the stop request comes from an object that was destroyed the | |
469 // callback was handled already. See OnStartNotificationsSuccess | |
470 // for more context. | |
471 if (callbacks != nullptr) { | |
Jeffrey Yasskin
2015/09/25 23:03:19
Do you mean callbacks or characteristic here? If t
ortuno
2015/09/29 22:47:36
callbacks is correct. Added:
An object is destroy
| |
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 | |
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 |