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_discovery_session_outcome.h"
18 #include "device/bluetooth/bluetooth_socket_thread.h"
19 #include "device/bluetooth/bluetooth_socket_win.h"
20 #include "device/bluetooth/bluetooth_task_manager_win.h"
21 #include "device/bluetooth/bluetooth_uuid.h"
26 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapter::CreateAdapter(
27 const InitCallback
& init_callback
) {
28 return BluetoothAdapterWin::CreateAdapter(init_callback
);
32 base::WeakPtr
<BluetoothAdapter
> BluetoothAdapterWin::CreateAdapter(
33 const InitCallback
& init_callback
) {
34 BluetoothAdapterWin
* adapter
= new BluetoothAdapterWin(init_callback
);
36 return adapter
->weak_ptr_factory_
.GetWeakPtr();
39 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback
& init_callback
)
41 init_callback_(init_callback
),
44 discovery_status_(NOT_DISCOVERING
),
45 num_discovery_listeners_(0),
46 weak_ptr_factory_(this) {
49 BluetoothAdapterWin::~BluetoothAdapterWin() {
50 if (task_manager_
.get()) {
51 task_manager_
->RemoveObserver(this);
52 task_manager_
->Shutdown();
56 std::string
BluetoothAdapterWin::GetAddress() const {
60 std::string
BluetoothAdapterWin::GetName() const {
64 void BluetoothAdapterWin::SetName(const std::string
& name
,
65 const base::Closure
& callback
,
66 const ErrorCallback
& error_callback
) {
70 // TODO(youngki): Return true when |task_manager_| initializes the adapter
72 bool BluetoothAdapterWin::IsInitialized() const {
76 bool BluetoothAdapterWin::IsPresent() const {
77 return !address_
.empty();
80 bool BluetoothAdapterWin::IsPowered() const {
84 void BluetoothAdapterWin::SetPowered(
86 const base::Closure
& callback
,
87 const ErrorCallback
& error_callback
) {
88 task_manager_
->PostSetPoweredBluetoothTask(powered
, callback
, error_callback
);
91 bool BluetoothAdapterWin::IsDiscoverable() const {
96 void BluetoothAdapterWin::SetDiscoverable(
98 const base::Closure
& callback
,
99 const ErrorCallback
& error_callback
) {
103 bool BluetoothAdapterWin::IsDiscovering() const {
104 return discovery_status_
== DISCOVERING
||
105 discovery_status_
== DISCOVERY_STOPPING
;
108 static void RunDiscoverySessionErrorCallback(
109 const base::Callback
<void(UMABluetoothDiscoverySessionOutcome
)>& callback
,
110 UMABluetoothDiscoverySessionOutcome outcome
) {
111 callback
.Run(outcome
);
114 void BluetoothAdapterWin::DiscoveryStarted(bool success
) {
115 discovery_status_
= success
? DISCOVERING
: NOT_DISCOVERING
;
116 for (const auto& callbacks
: on_start_discovery_callbacks_
) {
118 ui_task_runner_
->PostTask(FROM_HERE
, callbacks
.first
);
120 ui_task_runner_
->PostTask(
122 base::Bind(&RunDiscoverySessionErrorCallback
, callbacks
.second
,
123 UMABluetoothDiscoverySessionOutcome::UNKNOWN
));
125 num_discovery_listeners_
= on_start_discovery_callbacks_
.size();
126 on_start_discovery_callbacks_
.clear();
129 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
130 AdapterDiscoveringChanged(this, true));
132 // If there are stop discovery requests, post the stop discovery again.
133 MaybePostStopDiscoveryTask();
134 } else if (!on_stop_discovery_callbacks_
.empty()) {
135 // If there are stop discovery requests but start discovery has failed,
136 // notify that stop discovery has been complete.
141 void BluetoothAdapterWin::DiscoveryStopped() {
142 discovered_devices_
.clear();
143 bool was_discovering
= IsDiscovering();
144 discovery_status_
= NOT_DISCOVERING
;
145 for (std::vector
<base::Closure
>::const_iterator iter
=
146 on_stop_discovery_callbacks_
.begin();
147 iter
!= on_stop_discovery_callbacks_
.end();
149 ui_task_runner_
->PostTask(FROM_HERE
, *iter
);
151 num_discovery_listeners_
= 0;
152 on_stop_discovery_callbacks_
.clear();
154 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
155 AdapterDiscoveringChanged(this, false));
157 // If there are start discovery requests, post the start discovery again.
158 MaybePostStartDiscoveryTask();
161 void BluetoothAdapterWin::CreateRfcommService(
162 const BluetoothUUID
& uuid
,
163 const ServiceOptions
& options
,
164 const CreateServiceCallback
& callback
,
165 const CreateServiceErrorCallback
& error_callback
) {
166 scoped_refptr
<BluetoothSocketWin
> socket
=
167 BluetoothSocketWin::CreateBluetoothSocket(
168 ui_task_runner_
, socket_thread_
);
169 socket
->Listen(this, uuid
, options
,
170 base::Bind(callback
, socket
),
174 void BluetoothAdapterWin::CreateL2capService(
175 const BluetoothUUID
& uuid
,
176 const ServiceOptions
& options
,
177 const CreateServiceCallback
& callback
,
178 const CreateServiceErrorCallback
& error_callback
) {
179 // TODO(keybuk): implement.
183 void BluetoothAdapterWin::RegisterAudioSink(
184 const BluetoothAudioSink::Options
& options
,
185 const AcquiredCallback
& callback
,
186 const BluetoothAudioSink::ErrorCallback
& error_callback
) {
188 error_callback
.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM
);
191 void BluetoothAdapterWin::RegisterAdvertisement(
192 scoped_ptr
<BluetoothAdvertisement::Data
> advertisement_data
,
193 const CreateAdvertisementCallback
& callback
,
194 const CreateAdvertisementErrorCallback
& error_callback
) {
196 error_callback
.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM
);
199 void BluetoothAdapterWin::RemovePairingDelegateInternal(
200 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
203 void BluetoothAdapterWin::AdapterStateChanged(
204 const BluetoothTaskManagerWin::AdapterState
& state
) {
205 DCHECK(thread_checker_
.CalledOnValidThread());
207 bool was_present
= IsPresent();
208 bool is_present
= !state
.address
.empty();
209 address_
= BluetoothDevice::CanonicalizeAddress(state
.address
);
210 if (was_present
!= is_present
) {
211 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
212 AdapterPresentChanged(this, is_present
));
214 if (powered_
!= state
.powered
) {
215 powered_
= state
.powered
;
216 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
, observers_
,
217 AdapterPoweredChanged(this, powered_
));
221 init_callback_
.Run();
225 void BluetoothAdapterWin::DevicesPolled(
226 const ScopedVector
<BluetoothTaskManagerWin::DeviceState
>& devices
) {
227 DCHECK(thread_checker_
.CalledOnValidThread());
229 // We are receiving a new list of all devices known to the system. Merge this
230 // new list with the list we know of (|devices_|) and raise corresponding
231 // DeviceAdded, DeviceRemoved and DeviceChanged events.
233 typedef std::set
<std::string
> DeviceAddressSet
;
234 DeviceAddressSet known_devices
;
235 for (DevicesMap::const_iterator iter
= devices_
.begin();
236 iter
!= devices_
.end();
238 known_devices
.insert((*iter
).first
);
241 DeviceAddressSet new_devices
;
242 for (ScopedVector
<BluetoothTaskManagerWin::DeviceState
>::const_iterator iter
=
244 iter
!= devices
.end();
246 new_devices
.insert((*iter
)->address
);
249 // Process device removal first
250 DeviceAddressSet removed_devices
=
251 base::STLSetDifference
<DeviceAddressSet
>(known_devices
, new_devices
);
252 for (DeviceAddressSet::const_iterator iter
= removed_devices
.begin();
253 iter
!= removed_devices
.end();
255 BluetoothDevice
* device_win
= devices_
[(*iter
)];
256 devices_
.erase(*iter
);
257 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
259 DeviceRemoved(this, device_win
));
263 // Process added and (maybe) changed devices in one pass
264 DeviceAddressSet added_devices
=
265 base::STLSetDifference
<DeviceAddressSet
>(new_devices
, known_devices
);
266 DeviceAddressSet changed_devices
=
267 base::STLSetIntersection
<DeviceAddressSet
>(known_devices
, new_devices
);
268 for (ScopedVector
<BluetoothTaskManagerWin::DeviceState
>::const_iterator iter
=
270 iter
!= devices
.end();
272 BluetoothTaskManagerWin::DeviceState
* device_state
= (*iter
);
273 if (added_devices
.find(device_state
->address
) != added_devices
.end()) {
274 BluetoothDeviceWin
* device_win
=
275 new BluetoothDeviceWin(*device_state
,
279 net::NetLog::Source());
280 devices_
[device_state
->address
] = device_win
;
281 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
283 DeviceAdded(this, device_win
));
284 } else if (changed_devices
.find(device_state
->address
) !=
285 changed_devices
.end()) {
286 BluetoothDeviceWin
* device_win
=
287 static_cast<BluetoothDeviceWin
*>(devices_
[device_state
->address
]);
288 if (!device_win
->IsEqual(*device_state
)) {
289 device_win
->Update(*device_state
);
290 FOR_EACH_OBSERVER(BluetoothAdapter::Observer
,
292 DeviceChanged(this, device_win
));
298 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
299 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
300 void BluetoothAdapterWin::AddDiscoverySession(
301 BluetoothDiscoveryFilter
* discovery_filter
,
302 const base::Closure
& callback
,
303 const DiscoverySessionErrorCallback
& error_callback
) {
304 if (discovery_status_
== DISCOVERING
) {
305 num_discovery_listeners_
++;
309 on_start_discovery_callbacks_
.push_back(
310 std::make_pair(callback
, error_callback
));
311 MaybePostStartDiscoveryTask();
314 void BluetoothAdapterWin::RemoveDiscoverySession(
315 BluetoothDiscoveryFilter
* discovery_filter
,
316 const base::Closure
& callback
,
317 const DiscoverySessionErrorCallback
& error_callback
) {
318 if (discovery_status_
== NOT_DISCOVERING
) {
319 error_callback
.Run(UMABluetoothDiscoverySessionOutcome::NOT_ACTIVE
);
322 on_stop_discovery_callbacks_
.push_back(callback
);
323 MaybePostStopDiscoveryTask();
326 void BluetoothAdapterWin::SetDiscoveryFilter(
327 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
328 const base::Closure
& callback
,
329 const DiscoverySessionErrorCallback
& error_callback
) {
331 error_callback
.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED
);
334 void BluetoothAdapterWin::Init() {
335 ui_task_runner_
= base::ThreadTaskRunnerHandle::Get();
336 socket_thread_
= BluetoothSocketThread::Get();
338 new BluetoothTaskManagerWin(ui_task_runner_
);
339 task_manager_
->AddObserver(this);
340 task_manager_
->Initialize();
343 void BluetoothAdapterWin::InitForTest(
344 scoped_refptr
<base::SequencedTaskRunner
> ui_task_runner
,
345 scoped_refptr
<base::SequencedTaskRunner
> bluetooth_task_runner
) {
346 ui_task_runner_
= ui_task_runner
;
348 new BluetoothTaskManagerWin(ui_task_runner_
);
349 task_manager_
->AddObserver(this);
350 task_manager_
->InitializeWithBluetoothTaskRunner(bluetooth_task_runner
);
353 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
354 if (discovery_status_
== NOT_DISCOVERING
&&
355 !on_start_discovery_callbacks_
.empty()) {
356 discovery_status_
= DISCOVERY_STARTING
;
357 task_manager_
->PostStartDiscoveryTask();
361 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
362 if (discovery_status_
!= DISCOVERING
)
365 if (on_stop_discovery_callbacks_
.size() < num_discovery_listeners_
) {
366 for (std::vector
<base::Closure
>::const_iterator iter
=
367 on_stop_discovery_callbacks_
.begin();
368 iter
!= on_stop_discovery_callbacks_
.end();
370 ui_task_runner_
->PostTask(FROM_HERE
, *iter
);
372 num_discovery_listeners_
-= on_stop_discovery_callbacks_
.size();
373 on_stop_discovery_callbacks_
.clear();
377 discovery_status_
= DISCOVERY_STOPPING
;
378 task_manager_
->PostStopDiscoveryTask();
381 } // namespace device