1 // Copyright (c) 2012 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 "device/bluetooth/bluetooth_adapter_win.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/stl_util.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "device/bluetooth/bluetooth_device_win.h"
17 #include "device/bluetooth/bluetooth_socket_thread.h"
18 #include "device/bluetooth/bluetooth_socket_win.h"
19 #include "device/bluetooth/bluetooth_task_manager_win.h"
20 #include "device/bluetooth/bluetooth_uuid.h"
25 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::CreateAdapter(
26 const InitCallback
& init_callback
) {
27 return BluetoothAdapterWin::CreateAdapter(init_callback
);
31 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapterWin::CreateAdapter(
32 const InitCallback
& init_callback
) {
33 BluetoothAdapterWin
* adapter
= new BluetoothAdapterWin(init_callback
);
35 return adapter
->weak_ptr_factory_
.GetWeakPtr();
38 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback
& init_callback
)
40 init_callback_(init_callback
),
43 discovery_status_(NOT_DISCOVERING
),
44 num_discovery_listeners_(0),
45 weak_ptr_factory_(this) {
48 BluetoothAdapterWin::~BluetoothAdapterWin() {
49 if (task_manager_
.get()) {
50 task_manager_
->RemoveObserver(this);
51 task_manager_
->Shutdown();
55 std::string
BluetoothAdapterWin::GetAddress() const {
59 std::string
BluetoothAdapterWin::GetName() const {
63 void BluetoothAdapterWin::SetName(const std::string
& name
,
64 const base::Closure
& callback
,
65 const ErrorCallback
& error_callback
) {
69 // TODO(youngki): Return true when |task_manager_| initializes the adapter
71 bool BluetoothAdapterWin::IsInitialized() const {
75 bool BluetoothAdapterWin::IsPresent() const {
76 return !address_
.empty();
79 bool BluetoothAdapterWin::IsPowered() const {
83 void BluetoothAdapterWin::SetPowered(
85 const base::Closure
& callback
,
86 const ErrorCallback
& error_callback
) {
87 task_manager_
->PostSetPoweredBluetoothTask(powered
, callback
, error_callback
);
90 bool BluetoothAdapterWin::IsDiscoverable() const {
95 void BluetoothAdapterWin::SetDiscoverable(
97 const base::Closure
& callback
,
98 const ErrorCallback
& error_callback
) {
102 bool BluetoothAdapterWin::IsDiscovering() const {
103 return discovery_status_
== DISCOVERING
||
104 discovery_status_
== DISCOVERY_STOPPING
;
107 void BluetoothAdapterWin::DiscoveryStarted(bool success
) {
108 discovery_status_
= success
? DISCOVERING
: NOT_DISCOVERING
;
109 for (std::vector
<std::pair
<base::Closure
, ErrorCallback
> >::const_iterator
110 iter
= on_start_discovery_callbacks_
.begin();
111 iter
!= on_start_discovery_callbacks_
.end();
114 ui_task_runner_
->PostTask(FROM_HERE
, iter
->first
);
116 ui_task_runner_
->PostTask(FROM_HERE
, iter
->second
);
118 num_discovery_listeners_
= on_start_discovery_callbacks_
.size();
119 on_start_discovery_callbacks_
.clear();
122 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
123 AdapterDiscoveringChanged(this, true));
125 // If there are stop discovery requests, post the stop discovery again.
126 MaybePostStopDiscoveryTask();
127 } else if (!on_stop_discovery_callbacks_
.empty()) {
128 // If there are stop discovery requests but start discovery has failed,
129 // notify that stop discovery has been complete.
134 void BluetoothAdapterWin::DiscoveryStopped() {
135 discovered_devices_
.clear();
136 bool was_discovering
= IsDiscovering();
137 discovery_status_
= NOT_DISCOVERING
;
138 for (std::vector
<base::Closure
>::const_iterator iter
=
139 on_stop_discovery_callbacks_
.begin();
140 iter
!= on_stop_discovery_callbacks_
.end();
142 ui_task_runner_
->PostTask(FROM_HERE
, *iter
);
144 num_discovery_listeners_
= 0;
145 on_stop_discovery_callbacks_
.clear();
147 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
148 AdapterDiscoveringChanged(this, false));
150 // If there are start discovery requests, post the start discovery again.
151 MaybePostStartDiscoveryTask();
154 void BluetoothAdapterWin::CreateRfcommService(
155 const BluetoothUUID
& uuid
,
156 const ServiceOptions
& options
,
157 const CreateServiceCallback
& callback
,
158 const CreateServiceErrorCallback
& error_callback
) {
159 scoped_refptr
<BluetoothSocketWin
> socket
=
160 BluetoothSocketWin::CreateBluetoothSocket(
161 ui_task_runner_
, socket_thread_
);
162 socket
->Listen(this, uuid
, options
,
163 base::Bind(callback
, socket
),
167 void BluetoothAdapterWin::CreateL2capService(
168 const BluetoothUUID
& uuid
,
169 const ServiceOptions
& options
,
170 const CreateServiceCallback
& callback
,
171 const CreateServiceErrorCallback
& error_callback
) {
172 // TODO(keybuk): implement.
176 void BluetoothAdapterWin::RegisterAudioSink(
177 const BluetoothAudioSink::Options
& options
,
178 const AcquiredCallback
& callback
,
179 const BluetoothAudioSink::ErrorCallback
& error_callback
) {
181 error_callback
.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM
);
184 void BluetoothAdapterWin::RegisterAdvertisement(
185 scoped_ptr
<BluetoothAdvertisement::Data
> advertisement_data
,
186 const CreateAdvertisementCallback
& callback
,
187 const CreateAdvertisementErrorCallback
& error_callback
) {
189 error_callback
.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM
);
192 void BluetoothAdapterWin::RemovePairingDelegateInternal(
193 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
196 void BluetoothAdapterWin::AdapterStateChanged(
197 const BluetoothTaskManagerWin::AdapterState
& state
) {
198 DCHECK(thread_checker_
.CalledOnValidThread());
200 bool was_present
= IsPresent();
201 bool is_present
= !state
.address
.empty();
202 address_
= BluetoothDevice::CanonicalizeAddress(state
.address
);
203 if (was_present
!= is_present
) {
204 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
205 AdapterPresentChanged(this, is_present
));
207 if (powered_
!= state
.powered
) {
208 powered_
= state
.powered
;
209 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
210 AdapterPoweredChanged(this, powered_
));
214 init_callback_
.Run();
218 void BluetoothAdapterWin::DevicesPolled(
219 const ScopedVector
<BluetoothTaskManagerWin::DeviceState
>& devices
) {
220 DCHECK(thread_checker_
.CalledOnValidThread());
222 // We are receiving a new list of all devices known to the system. Merge this
223 // new list with the list we know of (|devices_|) and raise corresponding
224 // DeviceAdded, DeviceRemoved and DeviceChanged events.
226 typedef std::set
<std::string
> DeviceAddressSet
;
227 DeviceAddressSet known_devices
;
228 for (DevicesMap::const_iterator iter
= devices_
.begin();
229 iter
!= devices_
.end();
231 known_devices
.insert((*iter
).first
);
234 DeviceAddressSet new_devices
;
235 for (ScopedVector
<BluetoothTaskManagerWin::DeviceState
>::const_iterator iter
=
237 iter
!= devices
.end();
239 new_devices
.insert((*iter
)->address
);
242 // Process device removal first
243 DeviceAddressSet removed_devices
=
244 base::STLSetDifference
<DeviceAddressSet
>(known_devices
, new_devices
);
245 for (DeviceAddressSet::const_iterator iter
= removed_devices
.begin();
246 iter
!= removed_devices
.end();
248 BluetoothDevice
* device_win
= devices_
[(*iter
)];
249 devices_
.erase(*iter
);
250 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
252 DeviceRemoved(this, device_win
));
256 // Process added and (maybe) changed devices in one pass
257 DeviceAddressSet added_devices
=
258 base::STLSetDifference
<DeviceAddressSet
>(new_devices
, known_devices
);
259 DeviceAddressSet changed_devices
=
260 base::STLSetIntersection
<DeviceAddressSet
>(known_devices
, new_devices
);
261 for (ScopedVector
<BluetoothTaskManagerWin::DeviceState
>::const_iterator iter
=
263 iter
!= devices
.end();
265 BluetoothTaskManagerWin::DeviceState
* device_state
= (*iter
);
266 if (added_devices
.find(device_state
->address
) != added_devices
.end()) {
267 BluetoothDeviceWin
* device_win
=
268 new BluetoothDeviceWin(*device_state
,
272 net::NetLog::Source());
273 devices_
[device_state
->address
] = device_win
;
274 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
276 DeviceAdded(this, device_win
));
277 } else if (changed_devices
.find(device_state
->address
) !=
278 changed_devices
.end()) {
279 BluetoothDeviceWin
* device_win
=
280 static_cast<BluetoothDeviceWin
*>(devices_
[device_state
->address
]);
281 if (!device_win
->IsEqual(*device_state
)) {
282 device_win
->Update(*device_state
);
283 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
285 DeviceChanged(this, device_win
));
291 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
292 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
293 void BluetoothAdapterWin::AddDiscoverySession(
294 BluetoothDiscoveryFilter
* discovery_filter
,
295 const base::Closure
& callback
,
296 const ErrorCallback
& error_callback
) {
297 if (discovery_status_
== DISCOVERING
) {
298 num_discovery_listeners_
++;
302 on_start_discovery_callbacks_
.push_back(
303 std::make_pair(callback
, error_callback
));
304 MaybePostStartDiscoveryTask();
307 void BluetoothAdapterWin::RemoveDiscoverySession(
308 BluetoothDiscoveryFilter
* discovery_filter
,
309 const base::Closure
& callback
,
310 const ErrorCallback
& error_callback
) {
311 if (discovery_status_
== NOT_DISCOVERING
) {
312 error_callback
.Run();
315 on_stop_discovery_callbacks_
.push_back(callback
);
316 MaybePostStopDiscoveryTask();
319 void BluetoothAdapterWin::SetDiscoveryFilter(
320 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
321 const base::Closure
& callback
,
322 const ErrorCallback
& error_callback
) {
324 error_callback
.Run();
327 void BluetoothAdapterWin::Init() {
328 ui_task_runner_
= base::ThreadTaskRunnerHandle::Get();
329 socket_thread_
= BluetoothSocketThread::Get();
331 new BluetoothTaskManagerWin(ui_task_runner_
);
332 task_manager_
->AddObserver(this);
333 task_manager_
->Initialize();
336 void BluetoothAdapterWin::InitForTest(
337 scoped_refptr
<base::SequencedTaskRunner
> ui_task_runner
,
338 scoped_refptr
<base::SequencedTaskRunner
> bluetooth_task_runner
) {
339 ui_task_runner_
= ui_task_runner
;
341 new BluetoothTaskManagerWin(ui_task_runner_
);
342 task_manager_
->AddObserver(this);
343 task_manager_
->InitializeWithBluetoothTaskRunner(bluetooth_task_runner
);
346 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
347 if (discovery_status_
== NOT_DISCOVERING
&&
348 !on_start_discovery_callbacks_
.empty()) {
349 discovery_status_
= DISCOVERY_STARTING
;
350 task_manager_
->PostStartDiscoveryTask();
354 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
355 if (discovery_status_
!= DISCOVERING
)
358 if (on_stop_discovery_callbacks_
.size() < num_discovery_listeners_
) {
359 for (std::vector
<base::Closure
>::const_iterator iter
=
360 on_stop_discovery_callbacks_
.begin();
361 iter
!= on_stop_discovery_callbacks_
.end();
363 ui_task_runner_
->PostTask(FROM_HERE
, *iter
);
365 num_discovery_listeners_
-= on_stop_discovery_callbacks_
.size();
366 on_stop_discovery_callbacks_
.clear();
370 discovery_status_
= DISCOVERY_STOPPING
;
371 task_manager_
->PostStopDiscoveryTask();
374 } // namespace device