Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: content/renderer/bluetooth/bluetooth_dispatcher.cc

Issue 1334763002: bluetooth: Subscribe to notifications (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-origin
Patch Set: Add a comment about queueing system Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698