OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h" | 5 #include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/logging.h" |
| 11 #include "chromeos/dbus/dbus_thread_manager.h" |
| 12 #include "chromeos/dbus/experimental_bluetooth_adapter_client.h" |
| 13 #include "chromeos/dbus/experimental_bluetooth_device_client.h" |
| 14 #include "device/bluetooth/bluetooth_device.h" |
| 15 #include "device/bluetooth/bluetooth_device_experimental_chromeos.h" |
| 16 |
9 using device::BluetoothAdapter; | 17 using device::BluetoothAdapter; |
| 18 using device::BluetoothDevice; |
10 | 19 |
11 namespace chromeos { | 20 namespace chromeos { |
12 | 21 |
13 BluetoothAdapterExperimentalChromeOS::BluetoothAdapterExperimentalChromeOS() | 22 BluetoothAdapterExperimentalChromeOS::BluetoothAdapterExperimentalChromeOS() |
14 : BluetoothAdapter(), | 23 : weak_ptr_factory_(this) { |
15 weak_ptr_factory_(this) { | 24 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 25 AddObserver(this); |
| 26 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 27 AddObserver(this); |
| 28 |
| 29 std::vector<dbus::ObjectPath> object_paths = |
| 30 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 31 GetAdapters(); |
| 32 |
| 33 if (!object_paths.empty()) { |
| 34 VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available."; |
| 35 SetAdapter(object_paths[0]); |
| 36 } |
16 } | 37 } |
17 | 38 |
18 BluetoothAdapterExperimentalChromeOS::~BluetoothAdapterExperimentalChromeOS() { | 39 BluetoothAdapterExperimentalChromeOS::~BluetoothAdapterExperimentalChromeOS() { |
| 40 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 41 RemoveObserver(this); |
| 42 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 43 RemoveObserver(this); |
19 } | 44 } |
20 | 45 |
21 void BluetoothAdapterExperimentalChromeOS::AddObserver( | 46 void BluetoothAdapterExperimentalChromeOS::AddObserver( |
22 BluetoothAdapter::Observer* observer) { | 47 BluetoothAdapter::Observer* observer) { |
| 48 DCHECK(observer); |
| 49 observers_.AddObserver(observer); |
23 } | 50 } |
24 | 51 |
25 void BluetoothAdapterExperimentalChromeOS::RemoveObserver( | 52 void BluetoothAdapterExperimentalChromeOS::RemoveObserver( |
26 BluetoothAdapter::Observer* observer) { | 53 BluetoothAdapter::Observer* observer) { |
| 54 DCHECK(observer); |
| 55 observers_.RemoveObserver(observer); |
27 } | 56 } |
28 | 57 |
29 std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const { | 58 std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const { |
30 return std::string(); | 59 if (!IsPresent()) |
| 60 return std::string(); |
| 61 |
| 62 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 63 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 64 GetProperties(object_path_); |
| 65 DCHECK(properties); |
| 66 |
| 67 return properties->address.value(); |
31 } | 68 } |
32 | 69 |
33 std::string BluetoothAdapterExperimentalChromeOS::GetName() const { | 70 std::string BluetoothAdapterExperimentalChromeOS::GetName() const { |
34 return std::string(); | 71 if (!IsPresent()) |
| 72 return std::string(); |
| 73 |
| 74 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 75 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 76 GetProperties(object_path_); |
| 77 DCHECK(properties); |
| 78 |
| 79 return properties->alias.value(); |
35 } | 80 } |
36 | 81 |
37 bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const { | 82 bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const { |
38 return true; | 83 return true; |
39 } | 84 } |
40 | 85 |
41 bool BluetoothAdapterExperimentalChromeOS::IsPresent() const { | 86 bool BluetoothAdapterExperimentalChromeOS::IsPresent() const { |
42 return false; | 87 return !object_path_.value().empty(); |
43 } | 88 } |
44 | 89 |
45 bool BluetoothAdapterExperimentalChromeOS::IsPowered() const { | 90 bool BluetoothAdapterExperimentalChromeOS::IsPowered() const { |
46 return false; | 91 if (!IsPresent()) |
| 92 return false; |
| 93 |
| 94 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 95 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 96 GetProperties(object_path_); |
| 97 |
| 98 return properties->powered.value(); |
47 } | 99 } |
48 | 100 |
49 void BluetoothAdapterExperimentalChromeOS::SetPowered(bool powered, | 101 void BluetoothAdapterExperimentalChromeOS::SetPowered( |
50 const base::Closure& callback, | 102 bool powered, |
51 const ErrorCallback& error_callback) { | 103 const base::Closure& callback, |
52 error_callback.Run(); | 104 const ErrorCallback& error_callback) { |
| 105 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 106 GetProperties(object_path_)->powered.Set( |
| 107 powered, |
| 108 base::Bind(&BluetoothAdapterExperimentalChromeOS::OnSetPowered, |
| 109 weak_ptr_factory_.GetWeakPtr(), |
| 110 callback, |
| 111 error_callback)); |
53 } | 112 } |
54 | 113 |
55 bool BluetoothAdapterExperimentalChromeOS::IsDiscovering() const { | 114 bool BluetoothAdapterExperimentalChromeOS::IsDiscovering() const { |
56 return false; | 115 if (!IsPresent()) |
| 116 return false; |
| 117 |
| 118 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 119 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 120 GetProperties(object_path_); |
| 121 |
| 122 return properties->discovering.value(); |
57 } | 123 } |
58 | 124 |
59 void BluetoothAdapterExperimentalChromeOS::StartDiscovering( | 125 void BluetoothAdapterExperimentalChromeOS::StartDiscovering( |
60 const base::Closure& callback, | 126 const base::Closure& callback, |
61 const ErrorCallback& error_callback) { | 127 const ErrorCallback& error_callback) { |
62 error_callback.Run(); | 128 // BlueZ counts discovery sessions, and permits multiple sessions for a |
| 129 // single connection, so issue a StartDiscovery() call for every use |
| 130 // within Chromium for the right behavior. |
| 131 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 132 StartDiscovery( |
| 133 object_path_, |
| 134 base::Bind( |
| 135 &BluetoothAdapterExperimentalChromeOS::OnStartDiscovery, |
| 136 weak_ptr_factory_.GetWeakPtr(), |
| 137 callback), |
| 138 base::Bind( |
| 139 &BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError, |
| 140 weak_ptr_factory_.GetWeakPtr(), |
| 141 error_callback)); |
63 } | 142 } |
64 | 143 |
65 void BluetoothAdapterExperimentalChromeOS::StopDiscovering( | 144 void BluetoothAdapterExperimentalChromeOS::StopDiscovering( |
66 const base::Closure& callback, | 145 const base::Closure& callback, |
67 const ErrorCallback& error_callback) { | 146 const ErrorCallback& error_callback) { |
68 error_callback.Run(); | 147 // Inform BlueZ to stop one of our open discovery sessions. |
| 148 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 149 StopDiscovery( |
| 150 object_path_, |
| 151 base::Bind( |
| 152 &BluetoothAdapterExperimentalChromeOS::OnStopDiscovery, |
| 153 weak_ptr_factory_.GetWeakPtr(), |
| 154 callback), |
| 155 base::Bind( |
| 156 &BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError, |
| 157 weak_ptr_factory_.GetWeakPtr(), |
| 158 error_callback)); |
69 } | 159 } |
70 | 160 |
71 void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData( | 161 void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData( |
72 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, | 162 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, |
73 const ErrorCallback& error_callback) { | 163 const ErrorCallback& error_callback) { |
74 error_callback.Run(); | 164 error_callback.Run(); |
75 } | 165 } |
76 | 166 |
| 167 void BluetoothAdapterExperimentalChromeOS::AdapterAdded( |
| 168 const dbus::ObjectPath& object_path) { |
| 169 // Set the adapter to the newly added adapter only if no adapter is present. |
| 170 if (!IsPresent()) |
| 171 SetAdapter(object_path); |
| 172 } |
| 173 |
| 174 void BluetoothAdapterExperimentalChromeOS::AdapterRemoved( |
| 175 const dbus::ObjectPath& object_path) { |
| 176 if (object_path == object_path_) |
| 177 RemoveAdapter(); |
| 178 } |
| 179 |
| 180 void BluetoothAdapterExperimentalChromeOS::AdapterPropertyChanged( |
| 181 const dbus::ObjectPath& object_path, |
| 182 const std::string& property_name) { |
| 183 if (object_path != object_path_) |
| 184 return; |
| 185 |
| 186 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 187 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 188 GetProperties(object_path_); |
| 189 |
| 190 if (property_name == properties->powered.name()) |
| 191 PoweredChanged(properties->powered.value()); |
| 192 else if (property_name == properties->discovering.name()) |
| 193 DiscoveringChanged(properties->discovering.value()); |
| 194 } |
| 195 |
| 196 void BluetoothAdapterExperimentalChromeOS::DeviceAdded( |
| 197 const dbus::ObjectPath& object_path) { |
| 198 ExperimentalBluetoothDeviceClient::Properties* properties = |
| 199 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 200 GetProperties(object_path); |
| 201 if (properties->adapter.value() != object_path_) |
| 202 return; |
| 203 |
| 204 BluetoothDeviceExperimentalChromeOS* device_chromeos = |
| 205 new BluetoothDeviceExperimentalChromeOS(this, object_path); |
| 206 DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end()); |
| 207 |
| 208 devices_[device_chromeos->GetAddress()] = device_chromeos; |
| 209 |
| 210 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 211 DeviceAdded(this, device_chromeos)); |
| 212 } |
| 213 |
| 214 void BluetoothAdapterExperimentalChromeOS::DeviceRemoved( |
| 215 const dbus::ObjectPath& object_path) { |
| 216 for (DevicesMap::iterator iter = devices_.begin(); |
| 217 iter != devices_.end(); ++iter) { |
| 218 BluetoothDeviceExperimentalChromeOS* device_chromeos = |
| 219 static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second); |
| 220 if (device_chromeos->object_path() == object_path) { |
| 221 devices_.erase(iter); |
| 222 |
| 223 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 224 DeviceRemoved(this, device_chromeos)); |
| 225 delete device_chromeos; |
| 226 return; |
| 227 } |
| 228 } |
| 229 } |
| 230 |
| 231 void BluetoothAdapterExperimentalChromeOS::DevicePropertyChanged( |
| 232 const dbus::ObjectPath& object_path, |
| 233 const std::string& property_name) { |
| 234 BluetoothDeviceExperimentalChromeOS* device_chromeos = |
| 235 GetDeviceWithPath(object_path); |
| 236 if (!device_chromeos) |
| 237 return; |
| 238 |
| 239 ExperimentalBluetoothDeviceClient::Properties* properties = |
| 240 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 241 GetProperties(object_path); |
| 242 |
| 243 if (property_name == properties->bluetooth_class.name() || |
| 244 property_name == properties->alias.name() || |
| 245 property_name == properties->paired.name() || |
| 246 property_name == properties->connected.name() || |
| 247 property_name == properties->uuids.name()) { |
| 248 FOR_EACH_OBSERVER( |
| 249 BluetoothAdapter::Observer, observers_, |
| 250 DeviceChanged(this, device_chromeos)); |
| 251 } |
| 252 } |
| 253 |
| 254 BluetoothDeviceExperimentalChromeOS* |
| 255 BluetoothAdapterExperimentalChromeOS::GetDeviceWithPath( |
| 256 const dbus::ObjectPath& object_path) { |
| 257 for (DevicesMap::iterator iter = devices_.begin(); |
| 258 iter != devices_.end(); ++iter) { |
| 259 BluetoothDeviceExperimentalChromeOS* device_chromeos = |
| 260 static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second); |
| 261 if (device_chromeos->object_path() == object_path) |
| 262 return device_chromeos; |
| 263 } |
| 264 |
| 265 return NULL; |
| 266 } |
| 267 |
| 268 void BluetoothAdapterExperimentalChromeOS::SetAdapter( |
| 269 const dbus::ObjectPath& object_path) { |
| 270 DCHECK(!IsPresent()); |
| 271 object_path_ = object_path; |
| 272 |
| 273 VLOG(1) << object_path_.value() << ": using adapter."; |
| 274 |
| 275 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 276 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 277 GetProperties(object_path_); |
| 278 |
| 279 PresentChanged(true); |
| 280 |
| 281 if (properties->powered.value()) |
| 282 PoweredChanged(true); |
| 283 if (properties->discovering.value()) |
| 284 DiscoveringChanged(true); |
| 285 |
| 286 std::vector<dbus::ObjectPath> device_paths = |
| 287 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 288 GetDevicesForAdapter(object_path_); |
| 289 |
| 290 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin(); |
| 291 iter != device_paths.end(); ++iter) { |
| 292 BluetoothDeviceExperimentalChromeOS* device_chromeos = |
| 293 new BluetoothDeviceExperimentalChromeOS(this, *iter); |
| 294 |
| 295 devices_[device_chromeos->GetAddress()] = device_chromeos; |
| 296 |
| 297 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 298 DeviceAdded(this, device_chromeos)); |
| 299 } |
| 300 } |
| 301 |
| 302 void BluetoothAdapterExperimentalChromeOS::RemoveAdapter() { |
| 303 DCHECK(IsPresent()); |
| 304 VLOG(1) << object_path_.value() << ": adapter removed."; |
| 305 |
| 306 ExperimentalBluetoothAdapterClient::Properties* properties = |
| 307 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()-> |
| 308 GetProperties(object_path_); |
| 309 |
| 310 object_path_ = dbus::ObjectPath(""); |
| 311 |
| 312 if (properties->powered.value()) |
| 313 PoweredChanged(false); |
| 314 if (properties->discovering.value()) |
| 315 DiscoveringChanged(false); |
| 316 |
| 317 // Copy the devices list here and clear the original so that when we |
| 318 // send DeviceRemoved(), GetDevices() returns no devices. |
| 319 DevicesMap devices = devices_; |
| 320 devices_.clear(); |
| 321 |
| 322 for (DevicesMap::iterator iter = devices.begin(); |
| 323 iter != devices.end(); ++iter) { |
| 324 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 325 DeviceRemoved(this, iter->second)); |
| 326 delete iter->second; |
| 327 } |
| 328 |
| 329 PresentChanged(false); |
| 330 } |
| 331 |
| 332 void BluetoothAdapterExperimentalChromeOS::PoweredChanged(bool powered) { |
| 333 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 334 AdapterPoweredChanged(this, powered)); |
| 335 } |
| 336 |
| 337 void BluetoothAdapterExperimentalChromeOS::DiscoveringChanged( |
| 338 bool discovering) { |
| 339 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 340 AdapterDiscoveringChanged(this, discovering)); |
| 341 } |
| 342 |
| 343 void BluetoothAdapterExperimentalChromeOS::PresentChanged(bool present) { |
| 344 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 345 AdapterPresentChanged(this, present)); |
| 346 } |
| 347 |
| 348 void BluetoothAdapterExperimentalChromeOS::OnSetPowered( |
| 349 const base::Closure& callback, |
| 350 const ErrorCallback& error_callback, |
| 351 bool success) { |
| 352 if (success) |
| 353 callback.Run(); |
| 354 else |
| 355 error_callback.Run(); |
| 356 } |
| 357 |
| 358 void BluetoothAdapterExperimentalChromeOS::OnStartDiscovery( |
| 359 const base::Closure& callback) { |
| 360 callback.Run(); |
| 361 } |
| 362 |
| 363 void BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError( |
| 364 const ErrorCallback& error_callback, |
| 365 const std::string& error_name, |
| 366 const std::string& error_message) { |
| 367 LOG(WARNING) << object_path_.value() << ": Failed to start discovery: " |
| 368 << error_name << ": " << error_message; |
| 369 error_callback.Run(); |
| 370 } |
| 371 |
| 372 void BluetoothAdapterExperimentalChromeOS::OnStopDiscovery( |
| 373 const base::Closure& callback) { |
| 374 callback.Run(); |
| 375 } |
| 376 |
| 377 void BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError( |
| 378 const ErrorCallback& error_callback, |
| 379 const std::string& error_name, |
| 380 const std::string& error_message) { |
| 381 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: " |
| 382 << error_name << ": " << error_message; |
| 383 error_callback.Run(); |
| 384 } |
| 385 |
77 } // namespace chromeos | 386 } // namespace chromeos |
OLD | NEW |