Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / device / bluetooth / bluetooth_adapter_win.cc
blob009a50b237c32585a00e2b724d9245272f1f3f1f
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"
7 #include <string>
8 #include <utility>
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"
23 namespace device {
25 // static
26 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
27 const InitCallback& init_callback) {
28 return BluetoothAdapterWin::CreateAdapter(init_callback);
31 // static
32 base::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter(
33 const InitCallback& init_callback) {
34 BluetoothAdapterWin* adapter = new BluetoothAdapterWin(init_callback);
35 adapter->Init();
36 return adapter->weak_ptr_factory_.GetWeakPtr();
39 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
40 : BluetoothAdapter(),
41 init_callback_(init_callback),
42 initialized_(false),
43 powered_(false),
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 {
57 return address_;
60 std::string BluetoothAdapterWin::GetName() const {
61 return name_;
64 void BluetoothAdapterWin::SetName(const std::string& name,
65 const base::Closure& callback,
66 const ErrorCallback& error_callback) {
67 NOTIMPLEMENTED();
70 // TODO(youngki): Return true when |task_manager_| initializes the adapter
71 // state.
72 bool BluetoothAdapterWin::IsInitialized() const {
73 return initialized_;
76 bool BluetoothAdapterWin::IsPresent() const {
77 return !address_.empty();
80 bool BluetoothAdapterWin::IsPowered() const {
81 return powered_;
84 void BluetoothAdapterWin::SetPowered(
85 bool powered,
86 const base::Closure& callback,
87 const ErrorCallback& error_callback) {
88 task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
91 bool BluetoothAdapterWin::IsDiscoverable() const {
92 NOTIMPLEMENTED();
93 return false;
96 void BluetoothAdapterWin::SetDiscoverable(
97 bool discoverable,
98 const base::Closure& callback,
99 const ErrorCallback& error_callback) {
100 NOTIMPLEMENTED();
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_) {
117 if (success)
118 ui_task_runner_->PostTask(FROM_HERE, callbacks.first);
119 else
120 ui_task_runner_->PostTask(
121 FROM_HERE,
122 base::Bind(&RunDiscoverySessionErrorCallback, callbacks.second,
123 UMABluetoothDiscoverySessionOutcome::UNKNOWN));
125 num_discovery_listeners_ = on_start_discovery_callbacks_.size();
126 on_start_discovery_callbacks_.clear();
128 if (success) {
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.
137 DiscoveryStopped();
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();
148 ++iter) {
149 ui_task_runner_->PostTask(FROM_HERE, *iter);
151 num_discovery_listeners_ = 0;
152 on_stop_discovery_callbacks_.clear();
153 if (was_discovering)
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),
171 error_callback);
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.
180 NOTIMPLEMENTED();
183 void BluetoothAdapterWin::RegisterAudioSink(
184 const BluetoothAudioSink::Options& options,
185 const AcquiredCallback& callback,
186 const BluetoothAudioSink::ErrorCallback& error_callback) {
187 NOTIMPLEMENTED();
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) {
195 NOTIMPLEMENTED();
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());
206 name_ = state.name;
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_));
219 if (!initialized_) {
220 initialized_ = true;
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();
237 ++iter) {
238 known_devices.insert((*iter).first);
241 DeviceAddressSet new_devices;
242 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
243 devices.begin();
244 iter != devices.end();
245 ++iter) {
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();
254 ++iter) {
255 BluetoothDevice* device_win = devices_[(*iter)];
256 devices_.erase(*iter);
257 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
258 observers_,
259 DeviceRemoved(this, device_win));
260 delete 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 =
269 devices.begin();
270 iter != devices.end();
271 ++iter) {
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,
276 ui_task_runner_,
277 socket_thread_,
278 NULL,
279 net::NetLog::Source());
280 devices_[device_state->address] = device_win;
281 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
282 observers_,
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,
291 observers_,
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_++;
306 callback.Run();
307 return;
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);
320 return;
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) {
330 NOTIMPLEMENTED();
331 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED);
334 void BluetoothAdapterWin::Init() {
335 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
336 socket_thread_ = BluetoothSocketThread::Get();
337 task_manager_ =
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;
347 task_manager_ =
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)
363 return;
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();
369 ++iter) {
370 ui_task_runner_->PostTask(FROM_HERE, *iter);
372 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
373 on_stop_discovery_callbacks_.clear();
374 return;
377 discovery_status_ = DISCOVERY_STOPPING;
378 task_manager_->PostStopDiscoveryTask();
381 } // namespace device