Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / device / bluetooth / bluetooth_adapter_win.cc
blob2f32bd06b0d8cbf3bd5669a30e2d94c036a1bf47
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 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 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
109 discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
110 for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
111 iter = on_start_discovery_callbacks_.begin();
112 iter != on_start_discovery_callbacks_.end();
113 ++iter) {
114 if (success)
115 ui_task_runner_->PostTask(FROM_HERE, iter->first);
116 else
117 ui_task_runner_->PostTask(FROM_HERE, iter->second);
119 num_discovery_listeners_ = on_start_discovery_callbacks_.size();
120 on_start_discovery_callbacks_.clear();
122 if (success) {
123 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
124 AdapterDiscoveringChanged(this, true));
126 // If there are stop discovery requests, post the stop discovery again.
127 MaybePostStopDiscoveryTask();
128 } else if (!on_stop_discovery_callbacks_.empty()) {
129 // If there are stop discovery requests but start discovery has failed,
130 // notify that stop discovery has been complete.
131 DiscoveryStopped();
135 void BluetoothAdapterWin::DiscoveryStopped() {
136 discovered_devices_.clear();
137 bool was_discovering = IsDiscovering();
138 discovery_status_ = NOT_DISCOVERING;
139 for (std::vector<base::Closure>::const_iterator iter =
140 on_stop_discovery_callbacks_.begin();
141 iter != on_stop_discovery_callbacks_.end();
142 ++iter) {
143 ui_task_runner_->PostTask(FROM_HERE, *iter);
145 num_discovery_listeners_ = 0;
146 on_stop_discovery_callbacks_.clear();
147 if (was_discovering)
148 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
149 AdapterDiscoveringChanged(this, false));
151 // If there are start discovery requests, post the start discovery again.
152 MaybePostStartDiscoveryTask();
155 void BluetoothAdapterWin::CreateRfcommService(
156 const BluetoothUUID& uuid,
157 const ServiceOptions& options,
158 const CreateServiceCallback& callback,
159 const CreateServiceErrorCallback& error_callback) {
160 scoped_refptr<BluetoothSocketWin> socket =
161 BluetoothSocketWin::CreateBluetoothSocket(
162 ui_task_runner_, socket_thread_);
163 socket->Listen(this, uuid, options,
164 base::Bind(callback, socket),
165 error_callback);
168 void BluetoothAdapterWin::CreateL2capService(
169 const BluetoothUUID& uuid,
170 const ServiceOptions& options,
171 const CreateServiceCallback& callback,
172 const CreateServiceErrorCallback& error_callback) {
173 // TODO(keybuk): implement.
174 NOTIMPLEMENTED();
177 void BluetoothAdapterWin::RegisterAudioSink(
178 const BluetoothAudioSink::Options& options,
179 const AcquiredCallback& callback,
180 const BluetoothAudioSink::ErrorCallback& error_callback) {
181 NOTIMPLEMENTED();
182 error_callback.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM);
185 void BluetoothAdapterWin::RegisterAdvertisement(
186 scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
187 const CreateAdvertisementCallback& callback,
188 const CreateAdvertisementErrorCallback& error_callback) {
189 NOTIMPLEMENTED();
190 error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
193 void BluetoothAdapterWin::RemovePairingDelegateInternal(
194 BluetoothDevice::PairingDelegate* pairing_delegate) {
197 void BluetoothAdapterWin::AdapterStateChanged(
198 const BluetoothTaskManagerWin::AdapterState& state) {
199 DCHECK(thread_checker_.CalledOnValidThread());
200 name_ = state.name;
201 bool was_present = IsPresent();
202 bool is_present = !state.address.empty();
203 address_ = BluetoothDevice::CanonicalizeAddress(state.address);
204 if (was_present != is_present) {
205 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
206 AdapterPresentChanged(this, is_present));
208 if (powered_ != state.powered) {
209 powered_ = state.powered;
210 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
211 AdapterPoweredChanged(this, powered_));
213 if (!initialized_) {
214 initialized_ = true;
215 init_callback_.Run();
219 void BluetoothAdapterWin::DevicesPolled(
220 const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
221 DCHECK(thread_checker_.CalledOnValidThread());
223 // We are receiving a new list of all devices known to the system. Merge this
224 // new list with the list we know of (|devices_|) and raise corresponding
225 // DeviceAdded, DeviceRemoved and DeviceChanged events.
227 typedef std::set<std::string> DeviceAddressSet;
228 DeviceAddressSet known_devices;
229 for (DevicesMap::const_iterator iter = devices_.begin();
230 iter != devices_.end();
231 ++iter) {
232 known_devices.insert((*iter).first);
235 DeviceAddressSet new_devices;
236 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
237 devices.begin();
238 iter != devices.end();
239 ++iter) {
240 new_devices.insert((*iter)->address);
243 // Process device removal first
244 DeviceAddressSet removed_devices =
245 base::STLSetDifference<DeviceAddressSet>(known_devices, new_devices);
246 for (DeviceAddressSet::const_iterator iter = removed_devices.begin();
247 iter != removed_devices.end();
248 ++iter) {
249 BluetoothDevice* device_win = devices_[(*iter)];
250 devices_.erase(*iter);
251 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
252 observers_,
253 DeviceRemoved(this, device_win));
254 delete device_win;
257 // Process added and (maybe) changed devices in one pass
258 DeviceAddressSet added_devices =
259 base::STLSetDifference<DeviceAddressSet>(new_devices, known_devices);
260 DeviceAddressSet changed_devices =
261 base::STLSetIntersection<DeviceAddressSet>(known_devices, new_devices);
262 for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
263 devices.begin();
264 iter != devices.end();
265 ++iter) {
266 BluetoothTaskManagerWin::DeviceState* device_state = (*iter);
267 if (added_devices.find(device_state->address) != added_devices.end()) {
268 BluetoothDeviceWin* device_win =
269 new BluetoothDeviceWin(*device_state,
270 ui_task_runner_,
271 socket_thread_,
272 NULL,
273 net::NetLog::Source());
274 devices_[device_state->address] = device_win;
275 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
276 observers_,
277 DeviceAdded(this, device_win));
278 } else if (changed_devices.find(device_state->address) !=
279 changed_devices.end()) {
280 BluetoothDeviceWin* device_win =
281 static_cast<BluetoothDeviceWin*>(devices_[device_state->address]);
282 if (!device_win->IsEqual(*device_state)) {
283 device_win->Update(*device_state);
284 FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
285 observers_,
286 DeviceChanged(this, device_win));
292 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
293 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
294 void BluetoothAdapterWin::AddDiscoverySession(
295 BluetoothDiscoveryFilter* discovery_filter,
296 const base::Closure& callback,
297 const ErrorCallback& error_callback) {
298 if (discovery_status_ == DISCOVERING) {
299 num_discovery_listeners_++;
300 callback.Run();
301 return;
303 on_start_discovery_callbacks_.push_back(
304 std::make_pair(callback, error_callback));
305 MaybePostStartDiscoveryTask();
308 void BluetoothAdapterWin::RemoveDiscoverySession(
309 BluetoothDiscoveryFilter* discovery_filter,
310 const base::Closure& callback,
311 const ErrorCallback& error_callback) {
312 if (discovery_status_ == NOT_DISCOVERING) {
313 error_callback.Run();
314 return;
316 on_stop_discovery_callbacks_.push_back(callback);
317 MaybePostStopDiscoveryTask();
320 void BluetoothAdapterWin::SetDiscoveryFilter(
321 scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
322 const base::Closure& callback,
323 const ErrorCallback& error_callback) {
324 NOTIMPLEMENTED();
325 error_callback.Run();
328 void BluetoothAdapterWin::Init() {
329 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
330 socket_thread_ = BluetoothSocketThread::Get();
331 task_manager_ =
332 new BluetoothTaskManagerWin(ui_task_runner_);
333 task_manager_->AddObserver(this);
334 task_manager_->Initialize();
337 void BluetoothAdapterWin::InitForTest(
338 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
339 scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
340 ui_task_runner_ = ui_task_runner;
341 task_manager_ =
342 new BluetoothTaskManagerWin(ui_task_runner_);
343 task_manager_->AddObserver(this);
344 task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
347 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
348 if (discovery_status_ == NOT_DISCOVERING &&
349 !on_start_discovery_callbacks_.empty()) {
350 discovery_status_ = DISCOVERY_STARTING;
351 task_manager_->PostStartDiscoveryTask();
355 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
356 if (discovery_status_ != DISCOVERING)
357 return;
359 if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
360 for (std::vector<base::Closure>::const_iterator iter =
361 on_stop_discovery_callbacks_.begin();
362 iter != on_stop_discovery_callbacks_.end();
363 ++iter) {
364 ui_task_runner_->PostTask(FROM_HERE, *iter);
366 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
367 on_stop_discovery_callbacks_.clear();
368 return;
371 discovery_status_ = DISCOVERY_STOPPING;
372 task_manager_->PostStopDiscoveryTask();
375 } // namespace device