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_task_manager_win.h"
21 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
23 init_callback_(init_callback),
26 discovery_status_(NOT_DISCOVERING),
27 num_discovery_listeners_(0),
28 weak_ptr_factory_(this) {
31 BluetoothAdapterWin::~BluetoothAdapterWin() {
33 task_manager_->RemoveObserver(this);
34 task_manager_->Shutdown();
38 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
40 observers_.AddObserver(observer);
43 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
45 observers_.RemoveObserver(observer);
48 std::string BluetoothAdapterWin::GetAddress() const {
52 std::string BluetoothAdapterWin::GetName() const {
56 void BluetoothAdapterWin::SetName(const std::string& name,
57 const base::Closure& callback,
58 const ErrorCallback& error_callback) {
62 // TODO(youngki): Return true when |task_manager_| initializes the adapter
64 bool BluetoothAdapterWin::IsInitialized() const {
68 bool BluetoothAdapterWin::IsPresent() const {
69 return !address_.empty();
72 bool BluetoothAdapterWin::IsPowered() const {
76 void BluetoothAdapterWin::SetPowered(
78 const base::Closure& callback,
79 const ErrorCallback& error_callback) {
80 task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
83 bool BluetoothAdapterWin::IsDiscoverable() const {
88 void BluetoothAdapterWin::SetDiscoverable(
90 const base::Closure& callback,
91 const ErrorCallback& error_callback) {
95 bool BluetoothAdapterWin::IsDiscovering() const {
96 return discovery_status_ == DISCOVERING ||
97 discovery_status_ == DISCOVERY_STOPPING;
100 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
101 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
102 void BluetoothAdapterWin::StartDiscovering(
103 const base::Closure& callback,
104 const ErrorCallback& error_callback) {
105 if (discovery_status_ == DISCOVERING) {
106 num_discovery_listeners_++;
110 on_start_discovery_callbacks_.push_back(
111 std::make_pair(callback, error_callback));
112 MaybePostStartDiscoveryTask();
115 void BluetoothAdapterWin::StopDiscovering(
116 const base::Closure& callback,
117 const ErrorCallback& error_callback) {
118 if (discovery_status_ == NOT_DISCOVERING) {
119 error_callback.Run();
122 on_stop_discovery_callbacks_.push_back(callback);
123 MaybePostStopDiscoveryTask();
126 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
127 discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
128 for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
129 iter = on_start_discovery_callbacks_.begin();
130 iter != on_start_discovery_callbacks_.end();
133 ui_task_runner_->PostTask(FROM_HERE, iter->first);
135 ui_task_runner_->PostTask(FROM_HERE, iter->second);
137 num_discovery_listeners_ = on_start_discovery_callbacks_.size();
138 on_start_discovery_callbacks_.clear();
141 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
142 AdapterDiscoveringChanged(this, true));
144 // If there are stop discovery requests, post the stop discovery again.
145 MaybePostStopDiscoveryTask();
146 } else if (!on_stop_discovery_callbacks_.empty()) {
147 // If there are stop discovery requests but start discovery has failed,
148 // notify that stop discovery has been complete.
153 void BluetoothAdapterWin::DiscoveryStopped() {
154 discovered_devices_.clear();
155 bool was_discovering = IsDiscovering();
156 discovery_status_ = NOT_DISCOVERING;
157 for (std::vector<base::Closure>::const_iterator iter =
158 on_stop_discovery_callbacks_.begin();
159 iter != on_stop_discovery_callbacks_.end();
161 ui_task_runner_->PostTask(FROM_HERE, *iter);
163 num_discovery_listeners_ = 0;
164 on_stop_discovery_callbacks_.clear();
166 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
167 AdapterDiscoveringChanged(this, false));
169 // If there are start discovery requests, post the start discovery again.
170 MaybePostStartDiscoveryTask();
173 void BluetoothAdapterWin::ReadLocalOutOfBandPairingData(
174 const BluetoothOutOfBandPairingDataCallback& callback,
175 const ErrorCallback& error_callback) {
179 void BluetoothAdapterWin::AdapterStateChanged(
180 const BluetoothTaskManagerWin::AdapterState& state) {
181 DCHECK(thread_checker_.CalledOnValidThread());
183 bool was_present = IsPresent();
184 bool is_present = !state.address.empty();
185 address_ = state.address;
186 if (was_present != is_present) {
187 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
188 AdapterPresentChanged(this, is_present));
190 if (powered_ != state.powered) {
191 powered_ = state.powered;
192 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
193 AdapterPoweredChanged(this, powered_));
197 init_callback_.Run();
201 void BluetoothAdapterWin::DevicesDiscovered(
202 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
203 DCHECK(thread_checker_.CalledOnValidThread());
204 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
206 iter != devices.end();
208 if (discovered_devices_.find((*iter)->address) ==
209 discovered_devices_.end()) {
210 BluetoothDeviceWin device_win(**iter);
211 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
212 DeviceAdded(this, &device_win));
213 discovered_devices_.insert((*iter)->address);
218 void BluetoothAdapterWin::DevicesUpdated(
219 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
220 STLDeleteValues(&devices_);
221 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
223 iter != devices.end();
225 devices_[(*iter)->address] = new BluetoothDeviceWin(**iter);
229 void BluetoothAdapterWin::Init() {
230 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
232 new BluetoothTaskManagerWin(ui_task_runner_);
233 task_manager_->AddObserver(this);
234 task_manager_->Initialize();
237 void BluetoothAdapterWin::InitForTest(
238 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
239 scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
240 ui_task_runner_ = ui_task_runner;
242 new BluetoothTaskManagerWin(ui_task_runner_);
243 task_manager_->AddObserver(this);
244 task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
247 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
248 if (discovery_status_ == NOT_DISCOVERING &&
249 !on_start_discovery_callbacks_.empty()) {
250 discovery_status_ = DISCOVERY_STARTING;
251 task_manager_->PostStartDiscoveryTask();
255 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
256 if (discovery_status_ != DISCOVERING)
259 if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
260 for (std::vector<base::Closure>::const_iterator iter =
261 on_stop_discovery_callbacks_.begin();
262 iter != on_stop_discovery_callbacks_.end();
264 ui_task_runner_->PostTask(FROM_HERE, *iter);
266 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
267 on_stop_discovery_callbacks_.clear();
271 discovery_status_ = DISCOVERY_STOPPING;
272 task_manager_->PostStopDiscoveryTask();
275 } // namespace device