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"
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_task_manager_win.h"
23 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
24 const InitCallback& init_callback) {
25 return BluetoothAdapterWin::CreateAdapter(init_callback);
29 base::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter(
30 const InitCallback& init_callback) {
31 BluetoothAdapterWin* adapter = new BluetoothAdapterWin(init_callback);
33 return adapter->weak_ptr_factory_.GetWeakPtr();
36 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
38 init_callback_(init_callback),
41 discovery_status_(NOT_DISCOVERING),
42 num_discovery_listeners_(0),
43 weak_ptr_factory_(this) {
46 BluetoothAdapterWin::~BluetoothAdapterWin() {
48 task_manager_->RemoveObserver(this);
49 task_manager_->Shutdown();
53 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
55 observers_.AddObserver(observer);
58 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
60 observers_.RemoveObserver(observer);
63 std::string BluetoothAdapterWin::GetAddress() const {
67 std::string BluetoothAdapterWin::GetName() const {
71 void BluetoothAdapterWin::SetName(const std::string& name,
72 const base::Closure& callback,
73 const ErrorCallback& error_callback) {
77 // TODO(youngki): Return true when |task_manager_| initializes the adapter
79 bool BluetoothAdapterWin::IsInitialized() const {
83 bool BluetoothAdapterWin::IsPresent() const {
84 return !address_.empty();
87 bool BluetoothAdapterWin::IsPowered() const {
91 void BluetoothAdapterWin::SetPowered(
93 const base::Closure& callback,
94 const ErrorCallback& error_callback) {
95 task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
98 bool BluetoothAdapterWin::IsDiscoverable() const {
103 void BluetoothAdapterWin::SetDiscoverable(
105 const base::Closure& callback,
106 const ErrorCallback& error_callback) {
110 bool BluetoothAdapterWin::IsDiscovering() const {
111 return discovery_status_ == DISCOVERING ||
112 discovery_status_ == DISCOVERY_STOPPING;
115 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
116 discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
117 for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
118 iter = on_start_discovery_callbacks_.begin();
119 iter != on_start_discovery_callbacks_.end();
122 ui_task_runner_->PostTask(FROM_HERE, iter->first);
124 ui_task_runner_->PostTask(FROM_HERE, iter->second);
126 num_discovery_listeners_ = on_start_discovery_callbacks_.size();
127 on_start_discovery_callbacks_.clear();
130 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
131 AdapterDiscoveringChanged(this, true));
133 // If there are stop discovery requests, post the stop discovery again.
134 MaybePostStopDiscoveryTask();
135 } else if (!on_stop_discovery_callbacks_.empty()) {
136 // If there are stop discovery requests but start discovery has failed,
137 // notify that stop discovery has been complete.
142 void BluetoothAdapterWin::DiscoveryStopped() {
143 discovered_devices_.clear();
144 bool was_discovering = IsDiscovering();
145 discovery_status_ = NOT_DISCOVERING;
146 for (std::vector<base::Closure>::const_iterator iter =
147 on_stop_discovery_callbacks_.begin();
148 iter != on_stop_discovery_callbacks_.end();
150 ui_task_runner_->PostTask(FROM_HERE, *iter);
152 num_discovery_listeners_ = 0;
153 on_stop_discovery_callbacks_.clear();
155 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
156 AdapterDiscoveringChanged(this, false));
158 // If there are start discovery requests, post the start discovery again.
159 MaybePostStartDiscoveryTask();
162 void BluetoothAdapterWin::ReadLocalOutOfBandPairingData(
163 const BluetoothOutOfBandPairingDataCallback& callback,
164 const ErrorCallback& error_callback) {
168 void BluetoothAdapterWin::RemovePairingDelegateInternal(
169 BluetoothDevice::PairingDelegate* pairing_delegate) {
172 void BluetoothAdapterWin::AdapterStateChanged(
173 const BluetoothTaskManagerWin::AdapterState& state) {
174 DCHECK(thread_checker_.CalledOnValidThread());
176 bool was_present = IsPresent();
177 bool is_present = !state.address.empty();
178 address_ = state.address;
179 if (was_present != is_present) {
180 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
181 AdapterPresentChanged(this, is_present));
183 if (powered_ != state.powered) {
184 powered_ = state.powered;
185 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
186 AdapterPoweredChanged(this, powered_));
190 init_callback_.Run();
194 void BluetoothAdapterWin::DevicesDiscovered(
195 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
196 DCHECK(thread_checker_.CalledOnValidThread());
197 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
199 iter != devices.end();
201 if (discovered_devices_.find((*iter)->address) ==
202 discovered_devices_.end()) {
203 BluetoothDeviceWin device_win(
204 **iter, ui_task_runner_, socket_thread_, NULL, net::NetLog::Source());
205 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
206 DeviceAdded(this, &device_win));
207 discovered_devices_.insert((*iter)->address);
212 void BluetoothAdapterWin::DevicesUpdated(
213 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
214 STLDeleteValues(&devices_);
215 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
217 iter != devices.end();
219 devices_[(*iter)->address] = new BluetoothDeviceWin(
220 **iter, ui_task_runner_, socket_thread_, NULL, net::NetLog::Source());
224 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
225 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
226 void BluetoothAdapterWin::AddDiscoverySession(
227 const base::Closure& callback,
228 const ErrorCallback& error_callback) {
229 if (discovery_status_ == DISCOVERING) {
230 num_discovery_listeners_++;
234 on_start_discovery_callbacks_.push_back(
235 std::make_pair(callback, error_callback));
236 MaybePostStartDiscoveryTask();
239 void BluetoothAdapterWin::RemoveDiscoverySession(
240 const base::Closure& callback,
241 const ErrorCallback& error_callback) {
242 if (discovery_status_ == NOT_DISCOVERING) {
243 error_callback.Run();
246 on_stop_discovery_callbacks_.push_back(callback);
247 MaybePostStopDiscoveryTask();
250 void BluetoothAdapterWin::Init() {
251 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
252 socket_thread_ = BluetoothSocketThread::Get();
254 new BluetoothTaskManagerWin(ui_task_runner_);
255 task_manager_->AddObserver(this);
256 task_manager_->Initialize();
259 void BluetoothAdapterWin::InitForTest(
260 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
261 scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
262 ui_task_runner_ = ui_task_runner;
264 new BluetoothTaskManagerWin(ui_task_runner_);
265 task_manager_->AddObserver(this);
266 task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
269 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
270 if (discovery_status_ == NOT_DISCOVERING &&
271 !on_start_discovery_callbacks_.empty()) {
272 discovery_status_ = DISCOVERY_STARTING;
273 task_manager_->PostStartDiscoveryTask();
277 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
278 if (discovery_status_ != DISCOVERING)
281 if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
282 for (std::vector<base::Closure>::const_iterator iter =
283 on_stop_discovery_callbacks_.begin();
284 iter != on_stop_discovery_callbacks_.end();
286 ui_task_runner_->PostTask(FROM_HERE, *iter);
288 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
289 on_stop_discovery_callbacks_.clear();
293 discovery_status_ = DISCOVERY_STOPPING;
294 task_manager_->PostStopDiscoveryTask();
297 } // namespace device