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 25 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( 26 const InitCallback& init_callback) { 27 return BluetoothAdapterWin::CreateAdapter(init_callback); 28 } 29 30 // static 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 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 48 BluetoothAdapterWin::~BluetoothAdapterWin() { 49 if (task_manager_) { 50 task_manager_->RemoveObserver(this); 51 task_manager_->Shutdown(); 52 } 53 } 54 55 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) { 56 DCHECK(observer); 57 observers_.AddObserver(observer); 58 } 59 60 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) { 61 DCHECK(observer); 62 observers_.RemoveObserver(observer); 63 } 64 65 std::string BluetoothAdapterWin::GetAddress() const { 66 return address_; 67 } 68 69 std::string BluetoothAdapterWin::GetName() const { 70 return name_; 71 } 72 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. 81 bool BluetoothAdapterWin::IsInitialized() const { 82 return initialized_; 83 } 84 85 bool BluetoothAdapterWin::IsPresent() const { 86 return !address_.empty(); 87 } 88 89 bool BluetoothAdapterWin::IsPowered() const { 90 return powered_; 91 } 92 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 100 bool BluetoothAdapterWin::IsDiscoverable() const { 101 NOTIMPLEMENTED(); 102 return false; 103 } 104 105 void BluetoothAdapterWin::SetDiscoverable( 106 bool discoverable, 107 const base::Closure& callback, 108 const ErrorCallback& error_callback) { 109 NOTIMPLEMENTED(); 110 } 111 112 bool BluetoothAdapterWin::IsDiscovering() const { 113 return discovery_status_ == DISCOVERING || 114 discovery_status_ == DISCOVERY_STOPPING; 115 } 116 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 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 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 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 186 void BluetoothAdapterWin::RemovePairingDelegateInternal( 187 BluetoothDevice::PairingDelegate* pairing_delegate) { 188 } 189 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 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(). 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 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 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 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 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 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