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

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: Keep track of objects on the renderer side Created 5 years, 3 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 haracteristic.h"
18 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTC haracteristicDelegate.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::WebBluetoothGATTCharacteristic; 26 using blink::WebBluetoothGATTCharacteristic;
26 using blink::WebBluetoothGATTRemoteServer; 27 using blink::WebBluetoothGATTRemoteServer;
27 using blink::WebBluetoothGATTService; 28 using blink::WebBluetoothGATTService;
(...skipping 27 matching lines...) Expand all
55 : service_instance_id(service_instance_id), 56 : service_instance_id(service_instance_id),
56 characteristic_uuid(characteristic_uuid), 57 characteristic_uuid(characteristic_uuid),
57 callbacks(callbacks) {} 58 callbacks(callbacks) {}
58 ~BluetoothCharacteristicRequest() {} 59 ~BluetoothCharacteristicRequest() {}
59 60
60 blink::WebString service_instance_id; 61 blink::WebString service_instance_id;
61 blink::WebString characteristic_uuid; 62 blink::WebString characteristic_uuid;
62 scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks; 63 scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks;
63 }; 64 };
64 65
66 struct BluetoothNotificationsRequest {
67 BluetoothNotificationsRequest(
68 blink::WebString characteristic_instance_id,
69 blink::WebBluetoothGATTCharacteristicDelegate* delegate,
70 blink::WebBluetoothNotificationsCallbacks* callbacks)
71 : characteristic_instance_id(characteristic_instance_id),
72 delegate(delegate),
73 callbacks(callbacks) {}
74 ~BluetoothNotificationsRequest() {}
75
76 blink::WebString characteristic_instance_id;
77 blink::WebBluetoothGATTCharacteristicDelegate* delegate;
Jeffrey Yasskin 2015/09/15 03:45:37 Can you comment how we know |delegate| will stay a
ortuno 2015/09/15 21:38:19 Well the execution context on the blink side owns
78 scoped_ptr<blink::WebBluetoothNotificationsCallbacks> callbacks;
79 };
80
65 namespace content { 81 namespace content {
66 82
67 namespace { 83 namespace {
68 84
69 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = 85 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls =
70 LAZY_INSTANCE_INITIALIZER; 86 LAZY_INSTANCE_INITIALIZER;
71 87
72 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); 88 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1);
73 89
74 int CurrentWorkerId() { 90 int CurrentWorkerId() {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, 152 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError,
137 OnGetCharacteristicError); 153 OnGetCharacteristicError);
138 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, 154 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess,
139 OnReadValueSuccess); 155 OnReadValueSuccess);
140 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, 156 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError,
141 OnReadValueError); 157 OnReadValueError);
142 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, 158 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess,
143 OnWriteValueSuccess); 159 OnWriteValueSuccess);
144 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, 160 IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError,
145 OnWriteValueError); 161 OnWriteValueError);
162 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsSuccess,
163 OnStartNotificationsSuccess)
164 IPC_MESSAGE_HANDLER(BluetoothMsg_StartNotificationsError,
165 OnStartNotificationsError)
166 IPC_MESSAGE_HANDLER(BluetoothMsg_StopNotificationsSuccess,
167 OnStopNotificationsSuccess)
146 IPC_MESSAGE_UNHANDLED(handled = false) 168 IPC_MESSAGE_UNHANDLED(handled = false)
147 IPC_END_MESSAGE_MAP() 169 IPC_END_MESSAGE_MAP()
148 DCHECK(handled) << "Unhandled message:" << msg.type(); 170 DCHECK(handled) << "Unhandled message:" << msg.type();
149 } 171 }
150 172
151 void BluetoothDispatcher::requestDevice( 173 void BluetoothDispatcher::requestDevice(
152 int frame_routing_id, 174 int frame_routing_id,
153 const WebRequestDeviceOptions& options, 175 const WebRequestDeviceOptions& options,
154 blink::WebBluetoothRequestDeviceCallbacks* callbacks) { 176 blink::WebBluetoothRequestDeviceCallbacks* callbacks) {
155 int request_id = pending_requests_.Add(callbacks); 177 int request_id = pending_requests_.Add(callbacks);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 void BluetoothDispatcher::writeValue( 240 void BluetoothDispatcher::writeValue(
219 const blink::WebString& characteristic_instance_id, 241 const blink::WebString& characteristic_instance_id,
220 const std::vector<uint8_t>& value, 242 const std::vector<uint8_t>& value,
221 blink::WebBluetoothWriteValueCallbacks* callbacks) { 243 blink::WebBluetoothWriteValueCallbacks* callbacks) {
222 int request_id = pending_write_value_requests_.Add(callbacks); 244 int request_id = pending_write_value_requests_.Add(callbacks);
223 245
224 Send(new BluetoothHostMsg_WriteValue( 246 Send(new BluetoothHostMsg_WriteValue(
225 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); 247 CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value));
226 } 248 }
227 249
250 void BluetoothDispatcher::startNotifications(
251 const blink::WebString& characteristic_instance_id,
252 blink::WebBluetoothGATTCharacteristicDelegate* delegate,
253 blink::WebBluetoothNotificationsCallbacks* callbacks) {
254 // If an object is already subcribed to notifications from the characteristic,
255 // no need to subscribe to the dispatcher host again.
256 if (IsActiveCharacteristicNotification(characteristic_instance_id)) {
257 AddToActiveNotificationsMap(characteristic_instance_id, delegate);
258 callbacks->onSuccess();
259 return;
260 }
261
262 int request_id = pending_start_notifications_requests_.Add(
263 new BluetoothNotificationsRequest(characteristic_instance_id, delegate,
264 callbacks));
265
266 Send(new BluetoothHostMsg_StartNotifications(
Jeffrey Yasskin 2015/09/15 03:45:37 Since you're creating the active_notifications ent
ortuno 2015/09/15 21:38:19 That seems like an unnecessary optimization. Sendi
267 CurrentWorkerId(), request_id, characteristic_instance_id.utf8()));
268 }
269
270 void BluetoothDispatcher::stopNotifications(
271 const blink::WebString& characteristic_instance_id,
272 blink::WebBluetoothGATTCharacteristicDelegate* delegate,
273 blink::WebBluetoothNotificationsCallbacks* callbacks) {
274 // If this is not an active characteristic then no need to unsubscribe.
275 if (!IsActiveCharacteristicNotification(characteristic_instance_id)) {
Jeffrey Yasskin 2015/09/15 03:45:37 I think you don't need this check. Removing the el
ortuno 2015/09/15 21:38:19 Reworked this part. Calling stopNotifications twic
276 callbacks->onSuccess();
277 return;
278 }
279
280 RemoveFromActiveNotificationsMap(characteristic_instance_id, delegate);
281
282 // If the characteristic is still active no need to unsubscribe.
283 if (IsActiveCharacteristicNotification(characteristic_instance_id)) {
284 callbacks->onSuccess();
285 return;
286 }
287
288 int request_id = pending_stop_notifications_requests_.Add(
289 new BluetoothNotificationsRequest(characteristic_instance_id, delegate,
290 callbacks));
291
292 Send(new BluetoothHostMsg_StopNotifications(
293 CurrentWorkerId(), request_id, characteristic_instance_id.utf8()));
294 }
295
296 void BluetoothDispatcher::characteristicDelegateRemoved(
297 const blink::WebString& characteristic_instance_id,
298 blink::WebBluetoothGATTCharacteristicDelegate* delegate) {
299 RemoveFromActiveNotificationsMap(characteristic_instance_id, delegate);
300
301 // If the characteristic is still active no need to unsubscribe.
302 if (IsActiveCharacteristicNotification(characteristic_instance_id)) {
303 return;
304 }
305
306 // There could be a request pending on a delegate so we need to check
307 // the requests map. We ignore the stop request since we don't use
308 // the delegate in those.
309 for (IDMap<BluetoothNotificationsRequest, IDMapOwnPointer>::iterator iter(
310 &pending_start_notifications_requests_);
311 !iter.IsAtEnd(); iter.Advance()) {
312 iter.GetCurrentValue()->delegate = nullptr;
313 }
314 }
315
228 void BluetoothDispatcher::WillStopCurrentWorkerThread() { 316 void BluetoothDispatcher::WillStopCurrentWorkerThread() {
229 delete this; 317 delete this;
230 } 318 }
231 319
320 bool BluetoothDispatcher::IsActiveCharacteristicNotification(
321 const blink::WebString& characteristic_instance_id) {
322 auto char_iter = active_characteristic_notifications.find(
323 characteristic_instance_id.utf8());
324
325 // If this is the first object that is subscribing to notifications then
326 // the characteristic is not active.
327 if (char_iter == active_characteristic_notifications.end()) {
328 return false;
329 }
330
331 // If no object is subscribed to notifications then the characteristic
332 // is not active.
333 if (char_iter->second.size() == 0) {
Jeffrey Yasskin 2015/09/15 03:45:37 We should make sure that we remove elements from t
ortuno 2015/09/15 21:38:20 Done.
334 return false;
335 }
336 return true;
337 }
338
339 void BluetoothDispatcher::AddToActiveNotificationsMap(
340 const blink::WebString& characteristic_instance_id,
341 blink::WebBluetoothGATTCharacteristicDelegate* delegate) {
342 auto char_iter = active_characteristic_notifications.find(
Jeffrey Yasskin 2015/09/15 03:45:37 This is a good place to use operator[]: std::set<
ortuno 2015/09/15 21:38:20 I don't like adding the delegates to the map befor
343 characteristic_instance_id.utf8());
344
345 // First object that subscribes to notifications for the characteristic.
346 if (char_iter == active_characteristic_notifications.end()) {
347 std::set<blink::WebBluetoothGATTCharacteristicDelegate*> delegates;
348 delegates.insert(delegate);
349 active_characteristic_notifications.insert(
350 std::make_pair(characteristic_instance_id.utf8(), delegates));
351 return;
352 }
353 // Otherwise add to already existing set.
354 char_iter->second.insert(delegate);
355 }
356
357 void BluetoothDispatcher::RemoveFromActiveNotificationsMap(
358 const blink::WebString& characteristic_instance_id,
359 blink::WebBluetoothGATTCharacteristicDelegate* delegate) {
360 auto char_iter = active_characteristic_notifications.find(
361 characteristic_instance_id.utf8());
362
363 if (char_iter == active_characteristic_notifications.end()) {
364 return;
365 }
366
367 char_iter->second.erase(delegate);
Jeffrey Yasskin 2015/09/15 03:45:37 If the set became empty, remove it from the map he
ortuno 2015/09/15 21:38:20 Done.
368 }
369
232 void BluetoothDispatcher::OnRequestDeviceSuccess( 370 void BluetoothDispatcher::OnRequestDeviceSuccess(
233 int thread_id, 371 int thread_id,
234 int request_id, 372 int request_id,
235 const BluetoothDevice& device) { 373 const BluetoothDevice& device) {
236 DCHECK(pending_requests_.Lookup(request_id)) << request_id; 374 DCHECK(pending_requests_.Lookup(request_id)) << request_id;
237 375
238 WebVector<WebString> uuids(device.uuids.size()); 376 WebVector<WebString> uuids(device.uuids.size());
239 for (size_t i = 0; i < device.uuids.size(); ++i) 377 for (size_t i = 0; i < device.uuids.size(); ++i)
240 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); 378 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str());
241 379
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 int request_id, 517 int request_id,
380 WebBluetoothError error) { 518 WebBluetoothError error) {
381 DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id; 519 DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id;
382 520
383 pending_write_value_requests_.Lookup(request_id) 521 pending_write_value_requests_.Lookup(request_id)
384 ->onError(WebBluetoothError(error)); 522 ->onError(WebBluetoothError(error));
385 523
386 pending_write_value_requests_.Remove(request_id); 524 pending_write_value_requests_.Remove(request_id);
387 } 525 }
388 526
527 void BluetoothDispatcher::OnStartNotificationsSuccess(int thread_id,
528 int request_id) {
529 DCHECK(pending_start_notifications_requests_.Lookup(request_id))
530 << request_id;
531
532 BluetoothNotificationsRequest* request =
533 pending_start_notifications_requests_.Lookup(request_id);
534
535 // The object requesting the notification could have been destroyed
536 // while waiting for the subscription.
537 if (request->delegate != nullptr) {
Jeffrey Yasskin 2015/09/15 03:45:37 Could you comment that characteristicDelegateRemov
ortuno 2015/09/15 21:38:19 Done.
538 AddToActiveNotificationsMap(request->characteristic_instance_id,
539 request->delegate);
540 }
541 request->callbacks->onSuccess();
542
543 pending_start_notifications_requests_.Remove(request_id);
544 }
545
546 void BluetoothDispatcher::OnStartNotificationsError(int thread_id,
547 int request_id,
548 WebBluetoothError error) {
549 DCHECK(pending_start_notifications_requests_.Lookup(request_id))
550 << request_id;
551
552 pending_start_notifications_requests_.Lookup(request_id)
553 ->callbacks->onError(error);
554
555 pending_start_notifications_requests_.Remove(request_id);
556 }
557
558 void BluetoothDispatcher::OnStopNotificationsSuccess(int thread_id,
559 int request_id) {
560 DCHECK(pending_stop_notifications_requests_.Lookup(request_id)) << request_id;
561
562 BluetoothNotificationsRequest* request =
563 pending_stop_notifications_requests_.Lookup(request_id);
564
565 RemoveFromActiveNotificationsMap(request->characteristic_instance_id,
Jeffrey Yasskin 2015/09/15 03:45:37 You already called this before sending the stop IP
ortuno 2015/09/15 21:38:20 No longer calling this from stopNotifications.
566 request->delegate);
567
568 pending_stop_notifications_requests_.Lookup(request_id)
569 ->callbacks->onSuccess();
570
571 pending_stop_notifications_requests_.Remove(request_id);
572 }
573
389 } // namespace content 574 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698