Update UnusedResources lint suppressions.
[chromium-blink-merge.git] / content / child / bluetooth / bluetooth_dispatcher.cc
bloba9ad9903b04d130733f6c98e79dc966f252fed9c
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
3 // found in the LICENSE file.
5 #include "content/child/bluetooth/bluetooth_dispatcher.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/child/thread_safe_sender.h"
12 #include "content/common/bluetooth/bluetooth_messages.h"
13 #include "device/bluetooth/bluetooth_uuid.h"
14 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDevice.h"
15 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError.h"
16 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTCharacteristic.h"
17 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTRemoteServer.h"
18 #include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTService.h"
19 #include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h"
21 using blink::WebBluetoothConnectGATTCallbacks;
22 using blink::WebBluetoothDevice;
23 using blink::WebBluetoothError;
24 using blink::WebBluetoothGATTCharacteristic;
25 using blink::WebBluetoothGATTRemoteServer;
26 using blink::WebBluetoothGATTService;
27 using blink::WebBluetoothReadValueCallbacks;
28 using blink::WebBluetoothRequestDeviceCallbacks;
29 using blink::WebBluetoothScanFilter;
30 using blink::WebRequestDeviceOptions;
31 using blink::WebString;
32 using blink::WebVector;
34 struct BluetoothPrimaryServiceRequest {
35 BluetoothPrimaryServiceRequest(
36 blink::WebString device_instance_id,
37 blink::WebString service_uuid,
38 blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks)
39 : device_instance_id(device_instance_id),
40 service_uuid(service_uuid),
41 callbacks(callbacks) {}
42 ~BluetoothPrimaryServiceRequest() {}
44 blink::WebString device_instance_id;
45 blink::WebString service_uuid;
46 scoped_ptr<blink::WebBluetoothGetPrimaryServiceCallbacks> callbacks;
49 struct BluetoothCharacteristicRequest {
50 BluetoothCharacteristicRequest(
51 blink::WebString service_instance_id,
52 blink::WebString characteristic_uuid,
53 blink::WebBluetoothGetCharacteristicCallbacks* callbacks)
54 : service_instance_id(service_instance_id),
55 characteristic_uuid(characteristic_uuid),
56 callbacks(callbacks) {}
57 ~BluetoothCharacteristicRequest() {}
59 blink::WebString service_instance_id;
60 blink::WebString characteristic_uuid;
61 scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks;
64 namespace content {
66 namespace {
68 base::LazyInstance<base::ThreadLocalPointer<BluetoothDispatcher>>::Leaky
69 g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
71 BluetoothDispatcher* const kHasBeenDeleted =
72 reinterpret_cast<BluetoothDispatcher*>(0x1);
74 int CurrentWorkerId() {
75 return WorkerTaskRunner::Instance()->CurrentWorkerId();
78 WebBluetoothError::ErrorType WebBluetoothErrorFromBluetoothError(
79 BluetoothError error_type) {
80 switch (error_type) {
81 case BluetoothError::ABORT:
82 return WebBluetoothError::AbortError;
83 case BluetoothError::INVALID_MODIFICATION:
84 return WebBluetoothError::InvalidModificationError;
85 case BluetoothError::INVALID_STATE:
86 return WebBluetoothError::InvalidStateError;
87 case BluetoothError::NETWORK:
88 return WebBluetoothError::NetworkError;
89 case BluetoothError::NOT_FOUND:
90 return WebBluetoothError::NotFoundError;
91 case BluetoothError::NOT_SUPPORTED:
92 return WebBluetoothError::NotSupportedError;
93 case BluetoothError::SECURITY:
94 return WebBluetoothError::SecurityError;
95 case BluetoothError::SYNTAX:
96 return WebBluetoothError::SyntaxError;
98 NOTIMPLEMENTED();
99 return WebBluetoothError::NotFoundError;
102 WebBluetoothDevice::VendorIDSource GetWebVendorIdSource(
103 device::BluetoothDevice::VendorIDSource vendor_id_source) {
104 switch (vendor_id_source) {
105 case device::BluetoothDevice::VENDOR_ID_UNKNOWN:
106 return WebBluetoothDevice::VendorIDSource::Unknown;
107 case device::BluetoothDevice::VENDOR_ID_BLUETOOTH:
108 return WebBluetoothDevice::VendorIDSource::Bluetooth;
109 case device::BluetoothDevice::VENDOR_ID_USB:
110 return WebBluetoothDevice::VendorIDSource::USB;
112 NOTREACHED();
113 return WebBluetoothDevice::VendorIDSource::Unknown;
116 } // namespace
118 BluetoothDispatcher::BluetoothDispatcher(ThreadSafeSender* sender)
119 : thread_safe_sender_(sender) {
120 g_dispatcher_tls.Pointer()->Set(this);
123 BluetoothDispatcher::~BluetoothDispatcher() {
124 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
127 BluetoothDispatcher* BluetoothDispatcher::GetOrCreateThreadSpecificInstance(
128 ThreadSafeSender* thread_safe_sender) {
129 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
130 NOTREACHED() << "Re-instantiating TLS BluetoothDispatcher.";
131 g_dispatcher_tls.Pointer()->Set(NULL);
133 if (g_dispatcher_tls.Pointer()->Get())
134 return g_dispatcher_tls.Pointer()->Get();
136 BluetoothDispatcher* dispatcher = new BluetoothDispatcher(thread_safe_sender);
137 if (CurrentWorkerId())
138 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
139 return dispatcher;
142 bool BluetoothDispatcher::Send(IPC::Message* msg) {
143 return thread_safe_sender_->Send(msg);
146 void BluetoothDispatcher::OnMessageReceived(const IPC::Message& msg) {
147 bool handled = true;
148 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcher, msg)
149 IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceSuccess,
150 OnRequestDeviceSuccess);
151 IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceError, OnRequestDeviceError);
152 IPC_MESSAGE_HANDLER(BluetoothMsg_ConnectGATTSuccess, OnConnectGATTSuccess);
153 IPC_MESSAGE_HANDLER(BluetoothMsg_ConnectGATTError, OnConnectGATTError);
154 IPC_MESSAGE_HANDLER(BluetoothMsg_GetPrimaryServiceSuccess,
155 OnGetPrimaryServiceSuccess);
156 IPC_MESSAGE_HANDLER(BluetoothMsg_GetPrimaryServiceError,
157 OnGetPrimaryServiceError);
158 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicSuccess,
159 OnGetCharacteristicSuccess);
160 IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError,
161 OnGetCharacteristicError);
162 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess,
163 OnReadValueSuccess);
164 IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError,
165 OnReadValueError);
166 IPC_MESSAGE_UNHANDLED(handled = false)
167 IPC_END_MESSAGE_MAP()
168 DCHECK(handled) << "Unhandled message:" << msg.type();
171 void BluetoothDispatcher::requestDevice(
172 const WebRequestDeviceOptions& options,
173 blink::WebBluetoothRequestDeviceCallbacks* callbacks) {
174 int request_id = pending_requests_.Add(callbacks);
176 // Convert |options| to its IPC form.
177 std::vector<content::BluetoothScanFilter> filters(options.filters.size());
178 for (size_t i = 0; i < options.filters.size(); ++i) {
179 const WebBluetoothScanFilter& web_filter = options.filters[i];
180 BluetoothScanFilter& filter = filters[i];
181 filter.services.reserve(web_filter.services.size());
182 for (const WebString& service : web_filter.services) {
183 filter.services.push_back(device::BluetoothUUID(service.utf8()));
186 std::vector<device::BluetoothUUID> optional_services;
187 optional_services.reserve(options.optionalServices.size());
188 for (const WebString& optional_service : options.optionalServices) {
189 optional_services.push_back(device::BluetoothUUID(optional_service.utf8()));
192 Send(new BluetoothHostMsg_RequestDevice(CurrentWorkerId(), request_id,
193 filters, optional_services));
196 void BluetoothDispatcher::connectGATT(
197 const blink::WebString& device_instance_id,
198 blink::WebBluetoothConnectGATTCallbacks* callbacks) {
199 int request_id = pending_connect_requests_.Add(callbacks);
200 Send(new BluetoothHostMsg_ConnectGATT(CurrentWorkerId(), request_id,
201 device_instance_id.utf8()));
204 void BluetoothDispatcher::getPrimaryService(
205 const blink::WebString& device_instance_id,
206 const blink::WebString& service_uuid,
207 blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) {
208 int request_id =
209 pending_primary_service_requests_.Add(new BluetoothPrimaryServiceRequest(
210 device_instance_id, service_uuid, callbacks));
211 Send(new BluetoothHostMsg_GetPrimaryService(CurrentWorkerId(), request_id,
212 device_instance_id.utf8(),
213 service_uuid.utf8()));
216 void BluetoothDispatcher::getCharacteristic(
217 const blink::WebString& service_instance_id,
218 const blink::WebString& characteristic_uuid,
219 blink::WebBluetoothGetCharacteristicCallbacks* callbacks) {
220 int request_id =
221 pending_characteristic_requests_.Add(new BluetoothCharacteristicRequest(
222 service_instance_id, characteristic_uuid, callbacks));
223 Send(new BluetoothHostMsg_GetCharacteristic(CurrentWorkerId(), request_id,
224 service_instance_id.utf8(),
225 characteristic_uuid.utf8()));
228 void BluetoothDispatcher::readValue(
229 const blink::WebString& characteristic_instance_id,
230 blink::WebBluetoothReadValueCallbacks* callbacks) {
231 int request_id = pending_read_value_requests_.Add(callbacks);
232 Send(new BluetoothHostMsg_ReadValue(CurrentWorkerId(), request_id,
233 characteristic_instance_id.utf8()));
236 void BluetoothDispatcher::OnWorkerRunLoopStopped() {
237 delete this;
240 void BluetoothDispatcher::OnRequestDeviceSuccess(
241 int thread_id,
242 int request_id,
243 const BluetoothDevice& device) {
244 DCHECK(pending_requests_.Lookup(request_id)) << request_id;
246 WebVector<WebString> uuids(device.uuids.size());
247 for (size_t i = 0; i < device.uuids.size(); ++i)
248 uuids[i] = WebString::fromUTF8(device.uuids[i].c_str());
250 pending_requests_.Lookup(request_id)
251 ->onSuccess(new WebBluetoothDevice(
252 WebString::fromUTF8(device.instance_id), WebString(device.name),
253 device.device_class, GetWebVendorIdSource(device.vendor_id_source),
254 device.vendor_id, device.product_id, device.product_version,
255 device.paired, uuids));
256 pending_requests_.Remove(request_id);
259 void BluetoothDispatcher::OnRequestDeviceError(
260 int thread_id,
261 int request_id,
262 BluetoothError error_type,
263 const std::string& error_message) {
264 DCHECK(pending_requests_.Lookup(request_id)) << request_id;
265 pending_requests_.Lookup(request_id)
266 ->onError(new WebBluetoothError(
267 // TODO(ortuno): Return more descriptive error messages.
268 // http://crbug.com/490419
269 WebBluetoothErrorFromBluetoothError(error_type),
270 WebString::fromUTF8(error_message)));
271 pending_requests_.Remove(request_id);
274 void BluetoothDispatcher::OnConnectGATTSuccess(
275 int thread_id,
276 int request_id,
277 const std::string& device_instance_id) {
278 DCHECK(pending_connect_requests_.Lookup(request_id)) << request_id;
279 pending_connect_requests_.Lookup(request_id)
280 ->onSuccess(new WebBluetoothGATTRemoteServer(
281 WebString::fromUTF8(device_instance_id), true /* connected */));
282 pending_connect_requests_.Remove(request_id);
285 void BluetoothDispatcher::OnConnectGATTError(int thread_id,
286 int request_id,
287 BluetoothError error_type,
288 const std::string& error_message) {
289 DCHECK(pending_connect_requests_.Lookup(request_id)) << request_id;
290 pending_connect_requests_.Lookup(request_id)
291 ->onError(new WebBluetoothError(
292 // TODO(ortuno): Return more descriptive error messages.
293 // http://crbug.com/490419
294 WebBluetoothErrorFromBluetoothError(error_type),
295 WebString::fromUTF8(error_message)));
296 pending_connect_requests_.Remove(request_id);
299 void BluetoothDispatcher::OnGetPrimaryServiceSuccess(
300 int thread_id,
301 int request_id,
302 const std::string& service_instance_id) {
303 DCHECK(pending_primary_service_requests_.Lookup(request_id)) << request_id;
304 BluetoothPrimaryServiceRequest* request =
305 pending_primary_service_requests_.Lookup(request_id);
306 request->callbacks->onSuccess(new WebBluetoothGATTService(
307 WebString::fromUTF8(service_instance_id), request->service_uuid,
308 true /* isPrimary */, request->device_instance_id));
309 pending_primary_service_requests_.Remove(request_id);
312 void BluetoothDispatcher::OnGetPrimaryServiceError(
313 int thread_id,
314 int request_id,
315 BluetoothError error_type,
316 const std::string& error_message) {
317 DCHECK(pending_primary_service_requests_.Lookup(request_id)) << request_id;
319 // Since we couldn't find the service return null. See Step 3 of
320 // getPrimaryService algorithm:
321 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothgattremoteserver-getprimaryservice
322 if (error_type == BluetoothError::NOT_FOUND) {
323 pending_primary_service_requests_.Lookup(request_id)
324 ->callbacks->onSuccess(nullptr);
325 pending_primary_service_requests_.Remove(request_id);
326 return;
329 pending_primary_service_requests_.Lookup(request_id)
330 ->callbacks->onError(new WebBluetoothError(
331 // TODO(ortuno): Return more descriptive error messages.
332 // http://crbug.com/490419
333 WebBluetoothErrorFromBluetoothError(error_type),
334 WebString::fromUTF8(error_message)));
335 pending_primary_service_requests_.Remove(request_id);
338 void BluetoothDispatcher::OnGetCharacteristicSuccess(
339 int thread_id,
340 int request_id,
341 const std::string& characteristic_instance_id) {
342 DCHECK(pending_characteristic_requests_.Lookup(request_id)) << request_id;
344 BluetoothCharacteristicRequest* request =
345 pending_characteristic_requests_.Lookup(request_id);
346 request->callbacks->onSuccess(new WebBluetoothGATTCharacteristic(
347 WebString::fromUTF8(characteristic_instance_id),
348 request->service_instance_id, request->characteristic_uuid));
350 pending_characteristic_requests_.Remove(request_id);
353 void BluetoothDispatcher::OnGetCharacteristicError(
354 int thread_id,
355 int request_id,
356 BluetoothError error_type,
357 const std::string& error_message) {
358 DCHECK(pending_characteristic_requests_.Lookup(request_id)) << request_id;
360 // Since we couldn't find the characteristic return null. See Step 3 of
361 // getCharacteristic algorithm:
362 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothgattservice-getcharacteristic
363 if (error_type == BluetoothError::NOT_FOUND) {
364 pending_characteristic_requests_.Lookup(request_id)
365 ->callbacks->onSuccess(nullptr);
366 } else {
367 pending_characteristic_requests_.Lookup(request_id)
368 ->callbacks->onError(new WebBluetoothError(
369 // TODO(ortuno): Return more descriptive error messages.
370 // http://crbug.com/490419
371 WebBluetoothErrorFromBluetoothError(error_type),
372 WebString::fromUTF8(error_message)));
374 pending_characteristic_requests_.Remove(request_id);
377 void BluetoothDispatcher::OnReadValueSuccess(
378 int thread_id,
379 int request_id,
380 const std::vector<uint8_t>& value) {
381 DCHECK(pending_read_value_requests_.Lookup(request_id)) << request_id;
383 // WebArrayBuffer is not accessible from Source/modules so we pass a
384 // WebVector instead.
385 pending_read_value_requests_.Lookup(request_id)
386 ->onSuccess(new WebVector<uint8_t>(value));
388 pending_read_value_requests_.Remove(request_id);
391 void BluetoothDispatcher::OnReadValueError(int thread_id,
392 int request_id,
393 BluetoothError error_type,
394 const std::string& error_message) {
395 DCHECK(pending_read_value_requests_.Lookup(request_id)) << request_id;
397 pending_read_value_requests_.Lookup(request_id)
398 ->onError(new WebBluetoothError(
399 // TODO(ortuno): Return more descriptive error messages.
400 // http://crbug.com/490419
401 WebBluetoothErrorFromBluetoothError(error_type),
402 WebString::fromUTF8(error_message)));
404 pending_read_value_requests_.Remove(request_id);
407 } // namespace content