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 "third_party/WebKit/public/platform/WebBluetoothDevice.h"
14 #include "third_party/WebKit/public/platform/WebBluetoothError.h"
16 using blink::WebBluetoothDevice
;
17 using blink::WebBluetoothError
;
18 using blink::WebBluetoothRequestDeviceCallbacks
;
19 using blink::WebString
;
20 using blink::WebVector
;
26 base::LazyInstance
<base::ThreadLocalPointer
<BluetoothDispatcher
>>::Leaky
27 g_dispatcher_tls
= LAZY_INSTANCE_INITIALIZER
;
29 BluetoothDispatcher
* const kHasBeenDeleted
=
30 reinterpret_cast<BluetoothDispatcher
*>(0x1);
32 int CurrentWorkerId() {
33 return WorkerTaskRunner::Instance()->CurrentWorkerId();
36 WebBluetoothError::ErrorType
WebBluetoothErrorFromBluetoothError(
37 BluetoothError error_type
) {
39 case BluetoothError::NOT_FOUND
:
40 return WebBluetoothError::NotFoundError
;
41 case BluetoothError::SECURITY
:
42 return WebBluetoothError::SecurityError
;
45 return WebBluetoothError::NotFoundError
;
48 WebBluetoothDevice::VendorIDSource
GetWebVendorIdSource(
49 device::BluetoothDevice::VendorIDSource vendor_id_source
) {
50 switch (vendor_id_source
) {
51 case device::BluetoothDevice::VENDOR_ID_UNKNOWN
:
52 return WebBluetoothDevice::VendorIDSource::Unknown
;
53 case device::BluetoothDevice::VENDOR_ID_BLUETOOTH
:
54 return WebBluetoothDevice::VendorIDSource::Bluetooth
;
55 case device::BluetoothDevice::VENDOR_ID_USB
:
56 return WebBluetoothDevice::VendorIDSource::USB
;
59 return WebBluetoothDevice::VendorIDSource::Unknown
;
64 BluetoothDispatcher::BluetoothDispatcher(ThreadSafeSender
* sender
)
65 : thread_safe_sender_(sender
) {
66 g_dispatcher_tls
.Pointer()->Set(this);
69 BluetoothDispatcher::~BluetoothDispatcher() {
70 g_dispatcher_tls
.Pointer()->Set(kHasBeenDeleted
);
73 BluetoothDispatcher
* BluetoothDispatcher::GetOrCreateThreadSpecificInstance(
74 ThreadSafeSender
* thread_safe_sender
) {
75 if (g_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
) {
76 NOTREACHED() << "Re-instantiating TLS BluetoothDispatcher.";
77 g_dispatcher_tls
.Pointer()->Set(NULL
);
79 if (g_dispatcher_tls
.Pointer()->Get())
80 return g_dispatcher_tls
.Pointer()->Get();
82 BluetoothDispatcher
* dispatcher
= new BluetoothDispatcher(thread_safe_sender
);
83 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
84 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher
);
88 bool BluetoothDispatcher::Send(IPC::Message
* msg
) {
89 return thread_safe_sender_
->Send(msg
);
92 void BluetoothDispatcher::OnMessageReceived(const IPC::Message
& msg
) {
94 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcher
, msg
)
95 IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceSuccess
,
96 OnRequestDeviceSuccess
);
97 IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceError
, OnRequestDeviceError
);
98 IPC_MESSAGE_UNHANDLED(handled
= false)
100 DCHECK(handled
) << "Unhandled message:" << msg
.type();
103 void BluetoothDispatcher::requestDevice(
104 blink::WebBluetoothRequestDeviceCallbacks
* callbacks
) {
105 int request_id
= pending_requests_
.Add(callbacks
);
106 Send(new BluetoothHostMsg_RequestDevice(CurrentWorkerId(), request_id
));
109 void BluetoothDispatcher::SetBluetoothMockDataSetForTesting(
110 const std::string
& name
) {
111 Send(new BluetoothHostMsg_SetBluetoothMockDataSetForTesting(name
));
114 void BluetoothDispatcher::OnWorkerRunLoopStopped() {
118 void BluetoothDispatcher::OnRequestDeviceSuccess(
121 const BluetoothDevice
& device
) {
122 DCHECK(pending_requests_
.Lookup(request_id
)) << request_id
;
124 WebVector
<WebString
> uuids(device
.uuids
.size());
125 for (size_t i
= 0; i
< device
.uuids
.size(); ++i
)
126 uuids
[i
] = WebString::fromUTF8(device
.uuids
[i
].c_str());
128 pending_requests_
.Lookup(request_id
)
129 ->onSuccess(new WebBluetoothDevice(
130 WebString::fromUTF8(device
.instance_id
), WebString(device
.name
),
131 device
.device_class
, GetWebVendorIdSource(device
.vendor_id_source
),
132 device
.vendor_id
, device
.product_id
, device
.product_version
,
133 device
.paired
, device
.connected
, uuids
));
134 pending_requests_
.Remove(request_id
);
137 void BluetoothDispatcher::OnRequestDeviceError(int thread_id
,
139 BluetoothError error_type
) {
140 DCHECK(pending_requests_
.Lookup(request_id
)) << request_id
;
141 pending_requests_
.Lookup(request_id
)
142 ->onError(new WebBluetoothError(
143 WebBluetoothErrorFromBluetoothError(error_type
), ""));
144 pending_requests_
.Remove(request_id
);
147 } // namespace content