• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "device/bluetooth/bluetooth_adapter_win.h"
6 
7 #include <hash_set>
8 #include <string>
9 #include <utility>
10 
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_socket_win.h"
19 #include "device/bluetooth/bluetooth_task_manager_win.h"
20 #include "device/bluetooth/bluetooth_uuid.h"
21 
22 namespace device {
23 
24 // static
CreateAdapter(const InitCallback & init_callback)25 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
26     const InitCallback& init_callback) {
27   return BluetoothAdapterWin::CreateAdapter(init_callback);
28 }
29 
30 // static
CreateAdapter(const InitCallback & init_callback)31 base::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter(
32     const InitCallback& init_callback) {
33   BluetoothAdapterWin* adapter = new BluetoothAdapterWin(init_callback);
34   adapter->Init();
35   return adapter->weak_ptr_factory_.GetWeakPtr();
36 }
37 
BluetoothAdapterWin(const InitCallback & init_callback)38 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
39     : BluetoothAdapter(),
40       init_callback_(init_callback),
41       initialized_(false),
42       powered_(false),
43       discovery_status_(NOT_DISCOVERING),
44       num_discovery_listeners_(0),
45       weak_ptr_factory_(this) {
46 }
47 
~BluetoothAdapterWin()48 BluetoothAdapterWin::~BluetoothAdapterWin() {
49   if (task_manager_) {
50     task_manager_->RemoveObserver(this);
51     task_manager_->Shutdown();
52   }
53 }
54 
AddObserver(BluetoothAdapter::Observer * observer)55 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
56   DCHECK(observer);
57   observers_.AddObserver(observer);
58 }
59 
RemoveObserver(BluetoothAdapter::Observer * observer)60 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
61   DCHECK(observer);
62   observers_.RemoveObserver(observer);
63 }
64 
GetAddress() const65 std::string BluetoothAdapterWin::GetAddress() const {
66   return address_;
67 }
68 
GetName() const69 std::string BluetoothAdapterWin::GetName() const {
70   return name_;
71 }
72 
SetName(const std::string & name,const base::Closure & callback,const ErrorCallback & error_callback)73 void BluetoothAdapterWin::SetName(const std::string& name,
74                                   const base::Closure& callback,
75                                   const ErrorCallback& error_callback) {
76   NOTIMPLEMENTED();
77 }
78 
79 // TODO(youngki): Return true when |task_manager_| initializes the adapter
80 // state.
IsInitialized() const81 bool BluetoothAdapterWin::IsInitialized() const {
82   return initialized_;
83 }
84 
IsPresent() const85 bool BluetoothAdapterWin::IsPresent() const {
86   return !address_.empty();
87 }
88 
IsPowered() const89 bool BluetoothAdapterWin::IsPowered() const {
90   return powered_;
91 }
92 
SetPowered(bool powered,const base::Closure & callback,const ErrorCallback & error_callback)93 void BluetoothAdapterWin::SetPowered(
94     bool powered,
95     const base::Closure& callback,
96     const ErrorCallback& error_callback) {
97   task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
98 }
99 
IsDiscoverable() const100 bool BluetoothAdapterWin::IsDiscoverable() const {
101   NOTIMPLEMENTED();
102   return false;
103 }
104 
SetDiscoverable(bool discoverable,const base::Closure & callback,const ErrorCallback & error_callback)105 void BluetoothAdapterWin::SetDiscoverable(
106     bool discoverable,
107     const base::Closure& callback,
108     const ErrorCallback& error_callback) {
109   NOTIMPLEMENTED();
110 }
111 
IsDiscovering() const112 bool BluetoothAdapterWin::IsDiscovering() const {
113   return discovery_status_ == DISCOVERING ||
114       discovery_status_ == DISCOVERY_STOPPING;
115 }
116 
DiscoveryStarted(bool success)117 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
118   discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
119   for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
120        iter = on_start_discovery_callbacks_.begin();
121        iter != on_start_discovery_callbacks_.end();
122        ++iter) {
123     if (success)
124       ui_task_runner_->PostTask(FROM_HERE, iter->first);
125     else
126       ui_task_runner_->PostTask(FROM_HERE, iter->second);
127   }
128   num_discovery_listeners_ = on_start_discovery_callbacks_.size();
129   on_start_discovery_callbacks_.clear();
130 
131   if (success) {
132     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
133                       AdapterDiscoveringChanged(this, true));
134 
135     // If there are stop discovery requests, post the stop discovery again.
136     MaybePostStopDiscoveryTask();
137   } else if (!on_stop_discovery_callbacks_.empty()) {
138     // If there are stop discovery requests but start discovery has failed,
139     // notify that stop discovery has been complete.
140     DiscoveryStopped();
141   }
142 }
143 
DiscoveryStopped()144 void BluetoothAdapterWin::DiscoveryStopped() {
145   discovered_devices_.clear();
146   bool was_discovering = IsDiscovering();
147   discovery_status_ = NOT_DISCOVERING;
148   for (std::vector<base::Closure>::const_iterator iter =
149            on_stop_discovery_callbacks_.begin();
150        iter != on_stop_discovery_callbacks_.end();
151        ++iter) {
152     ui_task_runner_->PostTask(FROM_HERE, *iter);
153   }
154   num_discovery_listeners_ = 0;
155   on_stop_discovery_callbacks_.clear();
156   if (was_discovering)
157     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
158                       AdapterDiscoveringChanged(this, false));
159 
160   // If there are start discovery requests, post the start discovery again.
161   MaybePostStartDiscoveryTask();
162 }
163 
CreateRfcommService(const BluetoothUUID & uuid,const ServiceOptions & options,const CreateServiceCallback & callback,const CreateServiceErrorCallback & error_callback)164 void BluetoothAdapterWin::CreateRfcommService(
165     const BluetoothUUID& uuid,
166     const ServiceOptions& options,
167     const CreateServiceCallback& callback,
168     const CreateServiceErrorCallback& error_callback) {
169   scoped_refptr<BluetoothSocketWin> socket =
170       BluetoothSocketWin::CreateBluetoothSocket(
171           ui_task_runner_, socket_thread_);
172   socket->Listen(this, uuid, options,
173                  base::Bind(callback, socket),
174                  error_callback);
175 }
176 
CreateL2capService(const BluetoothUUID & uuid,const ServiceOptions & options,const CreateServiceCallback & callback,const CreateServiceErrorCallback & error_callback)177 void BluetoothAdapterWin::CreateL2capService(
178     const BluetoothUUID& uuid,
179     const ServiceOptions& options,
180     const CreateServiceCallback& callback,
181     const CreateServiceErrorCallback& error_callback) {
182   // TODO(keybuk): implement.
183   NOTIMPLEMENTED();
184 }
185 
RemovePairingDelegateInternal(BluetoothDevice::PairingDelegate * pairing_delegate)186 void BluetoothAdapterWin::RemovePairingDelegateInternal(
187     BluetoothDevice::PairingDelegate* pairing_delegate) {
188 }
189 
AdapterStateChanged(const BluetoothTaskManagerWin::AdapterState & state)190 void BluetoothAdapterWin::AdapterStateChanged(
191     const BluetoothTaskManagerWin::AdapterState& state) {
192   DCHECK(thread_checker_.CalledOnValidThread());
193   name_ = state.name;
194   bool was_present = IsPresent();
195   bool is_present = !state.address.empty();
196   address_ = BluetoothDevice::CanonicalizeAddress(state.address);
197   if (was_present != is_present) {
198     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
199                       AdapterPresentChanged(this, is_present));
200   }
201   if (powered_ != state.powered) {
202     powered_ = state.powered;
203     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
204                       AdapterPoweredChanged(this, powered_));
205   }
206   if (!initialized_) {
207     initialized_ = true;
208     init_callback_.Run();
209   }
210 }
211 
DevicesPolled(const ScopedVector<BluetoothTaskManagerWin::DeviceState> & devices)212 void BluetoothAdapterWin::DevicesPolled(
213     const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
214   DCHECK(thread_checker_.CalledOnValidThread());
215 
216   // We are receiving a new list of all devices known to the system. Merge this
217   // new list with the list we know of (|devices_|) and raise corresponding
218   // DeviceAdded, DeviceRemoved and DeviceChanged events.
219 
220   typedef std::set<std::string> DeviceAddressSet;
221   DeviceAddressSet known_devices;
222   for (DevicesMap::const_iterator iter = devices_.begin();
223        iter != devices_.end();
224        ++iter) {
225     known_devices.insert((*iter).first);
226   }
227 
228   DeviceAddressSet new_devices;
229   for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
230            devices.begin();
231        iter != devices.end();
232        ++iter) {
233     new_devices.insert((*iter)->address);
234   }
235 
236   // Process device removal first
237   DeviceAddressSet removed_devices =
238       base::STLSetDifference<DeviceAddressSet>(known_devices, new_devices);
239   for (DeviceAddressSet::const_iterator iter = removed_devices.begin();
240        iter != removed_devices.end();
241        ++iter) {
242     BluetoothDevice* device_win = devices_[(*iter)];
243     devices_.erase(*iter);
244     FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
245                       observers_,
246                       DeviceRemoved(this, device_win));
247     delete device_win;
248   }
249 
250   // Process added and (maybe) changed devices in one pass
251   DeviceAddressSet added_devices =
252       base::STLSetDifference<DeviceAddressSet>(new_devices, known_devices);
253   DeviceAddressSet changed_devices =
254       base::STLSetIntersection<DeviceAddressSet>(known_devices, new_devices);
255   for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
256            devices.begin();
257        iter != devices.end();
258        ++iter) {
259     BluetoothTaskManagerWin::DeviceState* device_state = (*iter);
260     if (added_devices.find(device_state->address) != added_devices.end()) {
261       BluetoothDeviceWin* device_win =
262           new BluetoothDeviceWin(*device_state,
263                                  ui_task_runner_,
264                                  socket_thread_,
265                                  NULL,
266                                  net::NetLog::Source());
267       devices_[device_state->address] = device_win;
268       FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
269                         observers_,
270                         DeviceAdded(this, device_win));
271     } else if (changed_devices.find(device_state->address) !=
272                changed_devices.end()) {
273       BluetoothDeviceWin* device_win =
274           static_cast<BluetoothDeviceWin*>(devices_[device_state->address]);
275       if (!device_win->IsEqual(*device_state)) {
276         device_win->Update(*device_state);
277         FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
278                           observers_,
279                           DeviceChanged(this, device_win));
280       }
281     }
282   }
283 }
284 
285 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
286 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
AddDiscoverySession(const base::Closure & callback,const ErrorCallback & error_callback)287 void BluetoothAdapterWin::AddDiscoverySession(
288     const base::Closure& callback,
289     const ErrorCallback& error_callback) {
290   if (discovery_status_ == DISCOVERING) {
291     num_discovery_listeners_++;
292     callback.Run();
293     return;
294   }
295   on_start_discovery_callbacks_.push_back(
296       std::make_pair(callback, error_callback));
297   MaybePostStartDiscoveryTask();
298 }
299 
RemoveDiscoverySession(const base::Closure & callback,const ErrorCallback & error_callback)300 void BluetoothAdapterWin::RemoveDiscoverySession(
301     const base::Closure& callback,
302     const ErrorCallback& error_callback) {
303   if (discovery_status_ == NOT_DISCOVERING) {
304     error_callback.Run();
305     return;
306   }
307   on_stop_discovery_callbacks_.push_back(callback);
308   MaybePostStopDiscoveryTask();
309 }
310 
Init()311 void BluetoothAdapterWin::Init() {
312   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
313   socket_thread_ = BluetoothSocketThread::Get();
314   task_manager_ =
315       new BluetoothTaskManagerWin(ui_task_runner_);
316   task_manager_->AddObserver(this);
317   task_manager_->Initialize();
318 }
319 
InitForTest(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner)320 void BluetoothAdapterWin::InitForTest(
321     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
322     scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
323   ui_task_runner_ = ui_task_runner;
324   task_manager_ =
325       new BluetoothTaskManagerWin(ui_task_runner_);
326   task_manager_->AddObserver(this);
327   task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
328 }
329 
MaybePostStartDiscoveryTask()330 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
331   if (discovery_status_ == NOT_DISCOVERING &&
332       !on_start_discovery_callbacks_.empty()) {
333     discovery_status_ = DISCOVERY_STARTING;
334     task_manager_->PostStartDiscoveryTask();
335   }
336 }
337 
MaybePostStopDiscoveryTask()338 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
339   if (discovery_status_ != DISCOVERING)
340     return;
341 
342   if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
343     for (std::vector<base::Closure>::const_iterator iter =
344              on_stop_discovery_callbacks_.begin();
345          iter != on_stop_discovery_callbacks_.end();
346          ++iter) {
347       ui_task_runner_->PostTask(FROM_HERE, *iter);
348     }
349     num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
350     on_stop_discovery_callbacks_.clear();
351     return;
352   }
353 
354   discovery_status_ = DISCOVERY_STOPPING;
355   task_manager_->PostStopDiscoveryTask();
356 }
357 
358 }  // namespace device
359