Mark //testing/perf target testonly.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_adapter_win.cc
blobfb28d7cda601da377c6a144184f3a17e582e95d8
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 <hash_set>
8 #include <string>
9 #include <utility>
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/stl_util.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "device/bluetooth/bluetooth_device_win.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 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
57 DCHECK(observer);
58 observers_.AddObserver(observer);
61 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
62 DCHECK(observer);
63 observers_.RemoveObserver(observer);
66 std::string BluetoothAdapterWin::GetAddress() const {
67 return address_;
70 std::string BluetoothAdapterWin::GetName() const {
71 return name_;
74 void BluetoothAdapterWin::SetName(const std::string& name,
75 const base::Closure& callback,
76 const ErrorCallback& error_callback) {
77 NOTIMPLEMENTED();
80 // TODO(youngki): Return true when |task_manager_| initializes the adapter
81 // state.
82 bool BluetoothAdapterWin::IsInitialized() const {
83 return initialized_;
86 bool BluetoothAdapterWin::IsPresent() const {
87 return !address_.empty();
90 bool BluetoothAdapterWin::IsPowered() const {
91 return powered_;
94 void BluetoothAdapterWin::SetPowered(
95 bool powered,
96 const base::Closure& callback,
97 const ErrorCallback& error_callback) {
98 task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
101 bool BluetoothAdapterWin::IsDiscoverable() const {
102 NOTIMPLEMENTED();
103 return false;
106 void BluetoothAdapterWin::SetDiscoverable(
107 bool discoverable,
108 const base::Closure& callback,
109 const ErrorCallback& error_callback) {
110 NOTIMPLEMENTED();
113 bool BluetoothAdapterWin::IsDiscovering() const {
114 return discovery_status_ == DISCOVERING ||
115 discovery_status_ == DISCOVERY_STOPPING;
118 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
119 discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
120 for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
121 iter = on_start_discovery_callbacks_.begin();
122 iter != on_start_discovery_callbacks_.end();
123 ++iter) {
124 if (success)
125 ui_task_runner_->PostTask(FROM_HERE, iter->first);
126 else
127 ui_task_runner_->PostTask(FROM_HERE, iter->second);
129 num_discovery_listeners_ = on_start_discovery_callbacks_.size();
130 on_start_discovery_callbacks_.clear();
132 if (success) {
133 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
134 AdapterDiscoveringChanged(this, true));
136 // If there are stop discovery requests, post the stop discovery again.
137 MaybePostStopDiscoveryTask();
138 } else if (!on_stop_discovery_callbacks_.empty()) {
139 // If there are stop discovery requests but start discovery has failed,
140 // notify that stop discovery has been complete.
141 DiscoveryStopped();
145 void BluetoothAdapterWin::DiscoveryStopped() {
146 discovered_devices_.clear();
147 bool was_discovering = IsDiscovering();
148 discovery_status_ = NOT_DISCOVERING;
149 for (std::vector<base::Closure>::const_iterator iter =
150 on_stop_discovery_callbacks_.begin();
151 iter != on_stop_discovery_callbacks_.end();
152 ++iter) {
153 ui_task_runner_->PostTask(FROM_HERE, *iter);
155 num_discovery_listeners_ = 0;
156 on_stop_discovery_callbacks_.clear();
157 if (was_discovering)
158 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
159 AdapterDiscoveringChanged(this, false));
161 // If there are start discovery requests, post the start discovery again.
162 MaybePostStartDiscoveryTask();
165 void BluetoothAdapterWin::CreateRfcommService(
166 const BluetoothUUID& uuid,
167 const ServiceOptions& options,
168 const CreateServiceCallback& callback,
169 const CreateServiceErrorCallback& error_callback) {
170 scoped_refptr<BluetoothSocketWin> socket =
171 BluetoothSocketWin::CreateBluetoothSocket(
172 ui_task_runner_, socket_thread_);
173 socket->Listen(this, uuid, options,
174 base::Bind(callback, socket),
175 error_callback);
178 void BluetoothAdapterWin::CreateL2capService(
179 const BluetoothUUID& uuid,
180 const ServiceOptions& options,
181 const CreateServiceCallback& callback,
182 const CreateServiceErrorCallback& error_callback) {
183 // TODO(keybuk): implement.
184 NOTIMPLEMENTED();
187 void BluetoothAdapterWin::RegisterAudioSink(
188 const BluetoothAudioSink::Options& options,
189 const AcquiredCallback& callback,
190 const BluetoothAudioSink::ErrorCallback& error_callback) {
191 NOTIMPLEMENTED();
192 error_callback.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM);
195 void BluetoothAdapterWin::RemovePairingDelegateInternal(
196 BluetoothDevice::PairingDelegate* pairing_delegate) {
199 void BluetoothAdapterWin::AdapterStateChanged(
200 const BluetoothTaskManagerWin::AdapterState& state) {
201 DCHECK(thread_checker_.CalledOnValidThread());
202 name_ = state.name;
203 bool was_present = IsPresent();
204 bool is_present = !state.address.empty();
205 address_ = BluetoothDevice::CanonicalizeAddress(state.address);
206 if (was_present != is_present) {
207 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
208 AdapterPresentChanged(this, is_present));
210 if (powered_ != state.powered) {
211 powered_ = state.powered;
212 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
213 AdapterPoweredChanged(this, powered_));
215 if (!initialized_) {
216 initialized_ = true;
217 init_callback_.Run();
221 void BluetoothAdapterWin::DevicesPolled(
222 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
223 DCHECK(thread_checker_.CalledOnValidThread());
225 // We are receiving a new list of all devices known to the system. Merge this
226 // new list with the list we know of (|devices_|) and raise corresponding
227 // DeviceAdded, DeviceRemoved and DeviceChanged events.
229 typedef std::set<std::string> DeviceAddressSet;
230 DeviceAddressSet known_devices;
231 for (DevicesMap::const_iterator iter = devices_.begin();
232 iter != devices_.end();
233 ++iter) {
234 known_devices.insert((*iter).first);
237 DeviceAddressSet new_devices;
238 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
239 devices.begin();
240 iter != devices.end();
241 ++iter) {
242 new_devices.insert((*iter)->address);
245 // Process device removal first
246 DeviceAddressSet removed_devices =
247 base::STLSetDifference<DeviceAddressSet>(known_devices, new_devices);
248 for (DeviceAddressSet::const_iterator iter = removed_devices.begin();
249 iter != removed_devices.end();
250 ++iter) {
251 BluetoothDevice* device_win = devices_[(*iter)];
252 devices_.erase(*iter);
253 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
254 observers_,
255 DeviceRemoved(this, device_win));
256 delete device_win;
259 // Process added and (maybe) changed devices in one pass
260 DeviceAddressSet added_devices =
261 base::STLSetDifference<DeviceAddressSet>(new_devices, known_devices);
262 DeviceAddressSet changed_devices =
263 base::STLSetIntersection<DeviceAddressSet>(known_devices, new_devices);
264 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
265 devices.begin();
266 iter != devices.end();
267 ++iter) {
268 BluetoothTaskManagerWin::DeviceState* device_state = (*iter);
269 if (added_devices.find(device_state->address) != added_devices.end()) {
270 BluetoothDeviceWin* device_win =
271 new BluetoothDeviceWin(*device_state,
272 ui_task_runner_,
273 socket_thread_,
274 NULL,
275 net::NetLog::Source());
276 devices_[device_state->address] = device_win;
277 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
278 observers_,
279 DeviceAdded(this, device_win));
280 } else if (changed_devices.find(device_state->address) !=
281 changed_devices.end()) {
282 BluetoothDeviceWin* device_win =
283 static_cast<BluetoothDeviceWin*>(devices_[device_state->address]);
284 if (!device_win->IsEqual(*device_state)) {
285 device_win->Update(*device_state);
286 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
287 observers_,
288 DeviceChanged(this, device_win));
294 void BluetoothAdapterWin::DeleteOnCorrectThread() const {
295 if (ui_task_runner_->RunsTasksOnCurrentThread() ||
296 !ui_task_runner_->DeleteSoon(FROM_HERE, this))
297 delete this;
300 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
301 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
302 void BluetoothAdapterWin::AddDiscoverySession(
303 const base::Closure& callback,
304 const ErrorCallback& error_callback) {
305 if (discovery_status_ == DISCOVERING) {
306 num_discovery_listeners_++;
307 callback.Run();
308 return;
310 on_start_discovery_callbacks_.push_back(
311 std::make_pair(callback, error_callback));
312 MaybePostStartDiscoveryTask();
315 void BluetoothAdapterWin::RemoveDiscoverySession(
316 const base::Closure& callback,
317 const ErrorCallback& error_callback) {
318 if (discovery_status_ == NOT_DISCOVERING) {
319 error_callback.Run();
320 return;
322 on_stop_discovery_callbacks_.push_back(callback);
323 MaybePostStopDiscoveryTask();
326 void BluetoothAdapterWin::Init() {
327 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
328 socket_thread_ = BluetoothSocketThread::Get();
329 task_manager_ =
330 new BluetoothTaskManagerWin(ui_task_runner_);
331 task_manager_->AddObserver(this);
332 task_manager_->Initialize();
335 void BluetoothAdapterWin::InitForTest(
336 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
337 scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
338 ui_task_runner_ = ui_task_runner;
339 task_manager_ =
340 new BluetoothTaskManagerWin(ui_task_runner_);
341 task_manager_->AddObserver(this);
342 task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
345 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
346 if (discovery_status_ == NOT_DISCOVERING &&
347 !on_start_discovery_callbacks_.empty()) {
348 discovery_status_ = DISCOVERY_STARTING;
349 task_manager_->PostStartDiscoveryTask();
353 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
354 if (discovery_status_ != DISCOVERING)
355 return;
357 if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
358 for (std::vector<base::Closure>::const_iterator iter =
359 on_stop_discovery_callbacks_.begin();
360 iter != on_stop_discovery_callbacks_.end();
361 ++iter) {
362 ui_task_runner_->PostTask(FROM_HERE, *iter);
364 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
365 on_stop_discovery_callbacks_.clear();
366 return;
369 discovery_status_ = DISCOVERY_STOPPING;
370 task_manager_->PostStopDiscoveryTask();
373 } // namespace device