| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ | |
| 6 #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <queue> | |
| 10 #include <string> | |
| 11 #include <utility> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/memory/weak_ptr.h" | |
| 15 #include "dbus/object_path.h" | |
| 16 #include "device/bluetooth/bluetooth_adapter.h" | |
| 17 #include "device/bluetooth/bluetooth_audio_sink.h" | |
| 18 #include "device/bluetooth/bluetooth_device.h" | |
| 19 #include "device/bluetooth/bluetooth_discovery_session.h" | |
| 20 #include "device/bluetooth/bluetooth_export.h" | |
| 21 #include "device/bluetooth/dbus/bluetooth_adapter_client.h" | |
| 22 #include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" | |
| 23 #include "device/bluetooth/dbus/bluetooth_device_client.h" | |
| 24 #include "device/bluetooth/dbus/bluetooth_input_client.h" | |
| 25 #include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" | |
| 26 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" | |
| 27 | |
| 28 namespace base { | |
| 29 class SequencedTaskRunner; | |
| 30 } // namespace base | |
| 31 | |
| 32 namespace device { | |
| 33 class BluetoothSocketThread; | |
| 34 } // namespace device | |
| 35 | |
| 36 namespace chromeos { | |
| 37 | |
| 38 class BluetoothChromeOSTest; | |
| 39 class BluetoothAdapterProfileChromeOS; | |
| 40 class BluetoothDeviceChromeOS; | |
| 41 class BluetoothPairingChromeOS; | |
| 42 class BluetoothRemoteGattCharacteristicChromeOS; | |
| 43 class BluetoothRemoteGattDescriptorChromeOS; | |
| 44 class BluetoothRemoteGattServiceChromeOS; | |
| 45 | |
| 46 // The BluetoothAdapterChromeOS class implements BluetoothAdapter for the | |
| 47 // Chrome OS platform. | |
| 48 // | |
| 49 // All methods are called from the dbus origin / UI thread and are generally | |
| 50 // not assumed to be thread-safe. | |
| 51 // | |
| 52 // This class interacts with sockets using the BluetoothSocketThread to ensure | |
| 53 // single-threaded calls, and posts tasks to the UI thread. | |
| 54 // | |
| 55 // Methods tolerate a shutdown scenario where BluetoothAdapterChromeOS::Shutdown | |
| 56 // causes IsPresent to return false just before the dbus system is shutdown but | |
| 57 // while references to the BluetoothAdapterChromeOS object still exists. | |
| 58 // | |
| 59 // When adding methods to this class verify shutdown behavior in | |
| 60 // BluetoothChromeOSTest, Shutdown. | |
| 61 class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS | |
| 62 : public device::BluetoothAdapter, | |
| 63 public bluez::BluetoothAdapterClient::Observer, | |
| 64 public bluez::BluetoothDeviceClient::Observer, | |
| 65 public bluez::BluetoothInputClient::Observer, | |
| 66 public bluez::BluetoothAgentServiceProvider::Delegate { | |
| 67 public: | |
| 68 typedef base::Callback<void(const std::string& error_message)> | |
| 69 ErrorCompletionCallback; | |
| 70 typedef base::Callback<void(BluetoothAdapterProfileChromeOS* profile)> | |
| 71 ProfileRegisteredCallback; | |
| 72 | |
| 73 static base::WeakPtr<BluetoothAdapter> CreateAdapter(); | |
| 74 | |
| 75 // BluetoothAdapter: | |
| 76 void Shutdown() override; | |
| 77 std::string GetAddress() const override; | |
| 78 std::string GetName() const override; | |
| 79 void SetName(const std::string& name, | |
| 80 const base::Closure& callback, | |
| 81 const ErrorCallback& error_callback) override; | |
| 82 bool IsInitialized() const override; | |
| 83 bool IsPresent() const override; | |
| 84 bool IsPowered() const override; | |
| 85 void SetPowered(bool powered, | |
| 86 const base::Closure& callback, | |
| 87 const ErrorCallback& error_callback) override; | |
| 88 bool IsDiscoverable() const override; | |
| 89 void SetDiscoverable(bool discoverable, | |
| 90 const base::Closure& callback, | |
| 91 const ErrorCallback& error_callback) override; | |
| 92 bool IsDiscovering() const override; | |
| 93 void CreateRfcommService( | |
| 94 const device::BluetoothUUID& uuid, | |
| 95 const ServiceOptions& options, | |
| 96 const CreateServiceCallback& callback, | |
| 97 const CreateServiceErrorCallback& error_callback) override; | |
| 98 void CreateL2capService( | |
| 99 const device::BluetoothUUID& uuid, | |
| 100 const ServiceOptions& options, | |
| 101 const CreateServiceCallback& callback, | |
| 102 const CreateServiceErrorCallback& error_callback) override; | |
| 103 void RegisterAudioSink( | |
| 104 const device::BluetoothAudioSink::Options& options, | |
| 105 const device::BluetoothAdapter::AcquiredCallback& callback, | |
| 106 const device::BluetoothAudioSink::ErrorCallback& error_callback) override; | |
| 107 | |
| 108 void RegisterAdvertisement( | |
| 109 scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data, | |
| 110 const CreateAdvertisementCallback& callback, | |
| 111 const CreateAdvertisementErrorCallback& error_callback) override; | |
| 112 | |
| 113 // Locates the device object by object path (the devices map and | |
| 114 // BluetoothDevice methods are by address). | |
| 115 BluetoothDeviceChromeOS* GetDeviceWithPath( | |
| 116 const dbus::ObjectPath& object_path); | |
| 117 | |
| 118 // Announces to observers a change in device state that is not reflected by | |
| 119 // its D-Bus properties. |device| is owned by the caller and cannot be NULL. | |
| 120 void NotifyDeviceChanged(BluetoothDeviceChromeOS* device); | |
| 121 | |
| 122 // Announce to observers a device address change. | |
| 123 void NotifyDeviceAddressChanged(BluetoothDeviceChromeOS* device, | |
| 124 const std::string& old_address); | |
| 125 | |
| 126 // The following methods are used to send various GATT observer events to | |
| 127 // observers. | |
| 128 void NotifyGattServiceAdded(BluetoothRemoteGattServiceChromeOS* service); | |
| 129 void NotifyGattServiceRemoved(BluetoothRemoteGattServiceChromeOS* service); | |
| 130 void NotifyGattServiceChanged(BluetoothRemoteGattServiceChromeOS* service); | |
| 131 void NotifyGattServicesDiscovered(BluetoothDeviceChromeOS* device); | |
| 132 void NotifyGattDiscoveryComplete(BluetoothRemoteGattServiceChromeOS* service); | |
| 133 void NotifyGattCharacteristicAdded( | |
| 134 BluetoothRemoteGattCharacteristicChromeOS* characteristic); | |
| 135 void NotifyGattCharacteristicRemoved( | |
| 136 BluetoothRemoteGattCharacteristicChromeOS* characteristic); | |
| 137 void NotifyGattDescriptorAdded( | |
| 138 BluetoothRemoteGattDescriptorChromeOS* descriptor); | |
| 139 void NotifyGattDescriptorRemoved( | |
| 140 BluetoothRemoteGattDescriptorChromeOS* descriptor); | |
| 141 void NotifyGattCharacteristicValueChanged( | |
| 142 BluetoothRemoteGattCharacteristicChromeOS* characteristic, | |
| 143 const std::vector<uint8>& value); | |
| 144 void NotifyGattDescriptorValueChanged( | |
| 145 BluetoothRemoteGattDescriptorChromeOS* descriptor, | |
| 146 const std::vector<uint8>& value); | |
| 147 | |
| 148 // Returns the object path of the adapter. | |
| 149 const dbus::ObjectPath& object_path() const { return object_path_; } | |
| 150 | |
| 151 // Request a profile on the adapter for a custom service with a | |
| 152 // specific UUID for the device at |device_path| to be sent to |delegate|. | |
| 153 // If |device_path| is the empty string, incoming connections will be | |
| 154 // assigned to |delegate|. When the profile is | |
| 155 // successfully registered, |success_callback| will be called with a pointer | |
| 156 // to the profile which is managed by BluetoothAdapterChromeOS. On failure, | |
| 157 // |error_callback| will be called. | |
| 158 void UseProfile(const device::BluetoothUUID& uuid, | |
| 159 const dbus::ObjectPath& device_path, | |
| 160 const bluez::BluetoothProfileManagerClient::Options& options, | |
| 161 bluez::BluetoothProfileServiceProvider::Delegate* delegate, | |
| 162 const ProfileRegisteredCallback& success_callback, | |
| 163 const ErrorCompletionCallback& error_callback); | |
| 164 | |
| 165 // Release use of a profile by a device. | |
| 166 void ReleaseProfile(const dbus::ObjectPath& device_path, | |
| 167 BluetoothAdapterProfileChromeOS* profile); | |
| 168 | |
| 169 protected: | |
| 170 // BluetoothAdapter: | |
| 171 void RemovePairingDelegateInternal( | |
| 172 device::BluetoothDevice::PairingDelegate* pairing_delegate) override; | |
| 173 | |
| 174 private: | |
| 175 friend class BluetoothChromeOSTest; | |
| 176 friend class BluetoothChromeOSTest_Shutdown_Test; | |
| 177 friend class BluetoothChromeOSTest_Shutdown_OnStartDiscovery_Test; | |
| 178 friend class BluetoothChromeOSTest_Shutdown_OnStartDiscoveryError_Test; | |
| 179 friend class BluetoothChromeOSTest_Shutdown_OnStopDiscovery_Test; | |
| 180 friend class BluetoothChromeOSTest_Shutdown_OnStopDiscoveryError_Test; | |
| 181 | |
| 182 // typedef for callback parameters that are passed to AddDiscoverySession | |
| 183 // and RemoveDiscoverySession. This is used to queue incoming requests while | |
| 184 // a call to BlueZ is pending. | |
| 185 typedef std::tuple<device::BluetoothDiscoveryFilter*, | |
| 186 base::Closure, | |
| 187 DiscoverySessionErrorCallback> DiscoveryParamTuple; | |
| 188 typedef std::queue<DiscoveryParamTuple> DiscoveryCallbackQueue; | |
| 189 | |
| 190 // Callback pair for the profile registration queue. | |
| 191 typedef std::pair<base::Closure, ErrorCompletionCallback> | |
| 192 RegisterProfileCompletionPair; | |
| 193 | |
| 194 BluetoothAdapterChromeOS(); | |
| 195 ~BluetoothAdapterChromeOS() override; | |
| 196 | |
| 197 // bluez::BluetoothAdapterClient::Observer override. | |
| 198 void AdapterAdded(const dbus::ObjectPath& object_path) override; | |
| 199 void AdapterRemoved(const dbus::ObjectPath& object_path) override; | |
| 200 void AdapterPropertyChanged(const dbus::ObjectPath& object_path, | |
| 201 const std::string& property_name) override; | |
| 202 | |
| 203 // bluez::BluetoothDeviceClient::Observer override. | |
| 204 void DeviceAdded(const dbus::ObjectPath& object_path) override; | |
| 205 void DeviceRemoved(const dbus::ObjectPath& object_path) override; | |
| 206 void DevicePropertyChanged(const dbus::ObjectPath& object_path, | |
| 207 const std::string& property_name) override; | |
| 208 | |
| 209 // bluez::BluetoothInputClient::Observer override. | |
| 210 void InputPropertyChanged(const dbus::ObjectPath& object_path, | |
| 211 const std::string& property_name) override; | |
| 212 | |
| 213 // bluez::BluetoothAgentServiceProvider::Delegate override. | |
| 214 void Released() override; | |
| 215 void RequestPinCode(const dbus::ObjectPath& device_path, | |
| 216 const PinCodeCallback& callback) override; | |
| 217 void DisplayPinCode(const dbus::ObjectPath& device_path, | |
| 218 const std::string& pincode) override; | |
| 219 void RequestPasskey(const dbus::ObjectPath& device_path, | |
| 220 const PasskeyCallback& callback) override; | |
| 221 void DisplayPasskey(const dbus::ObjectPath& device_path, | |
| 222 uint32 passkey, | |
| 223 uint16 entered) override; | |
| 224 void RequestConfirmation(const dbus::ObjectPath& device_path, | |
| 225 uint32 passkey, | |
| 226 const ConfirmationCallback& callback) override; | |
| 227 void RequestAuthorization(const dbus::ObjectPath& device_path, | |
| 228 const ConfirmationCallback& callback) override; | |
| 229 void AuthorizeService(const dbus::ObjectPath& device_path, | |
| 230 const std::string& uuid, | |
| 231 const ConfirmationCallback& callback) override; | |
| 232 void Cancel() override; | |
| 233 | |
| 234 // Called by dbus:: on completion of the D-Bus method call to register the | |
| 235 // pairing agent. | |
| 236 void OnRegisterAgent(); | |
| 237 void OnRegisterAgentError(const std::string& error_name, | |
| 238 const std::string& error_message); | |
| 239 | |
| 240 // Called by dbus:: on completion of the D-Bus method call to request that | |
| 241 // the pairing agent be made the default. | |
| 242 void OnRequestDefaultAgent(); | |
| 243 void OnRequestDefaultAgentError(const std::string& error_name, | |
| 244 const std::string& error_message); | |
| 245 | |
| 246 // Called by BluetoothAudioSinkChromeOS on completion of registering an audio | |
| 247 // sink. | |
| 248 void OnRegisterAudioSink( | |
| 249 const device::BluetoothAdapter::AcquiredCallback& callback, | |
| 250 const device::BluetoothAudioSink::ErrorCallback& error_callback, | |
| 251 scoped_refptr<device::BluetoothAudioSink> audio_sink); | |
| 252 | |
| 253 // Internal method to obtain a BluetoothPairingChromeOS object for the device | |
| 254 // with path |object_path|. Returns the existing pairing object if the device | |
| 255 // already has one (usually an outgoing connection in progress) or a new | |
| 256 // pairing object with the default pairing delegate if not. If no default | |
| 257 // pairing object exists, NULL will be returned. | |
| 258 BluetoothPairingChromeOS* GetPairing(const dbus::ObjectPath& object_path); | |
| 259 | |
| 260 // Set the tracked adapter to the one in |object_path|, this object will | |
| 261 // subsequently operate on that adapter until it is removed. | |
| 262 void SetAdapter(const dbus::ObjectPath& object_path); | |
| 263 | |
| 264 // Set the adapter name to one chosen from the system information. | |
| 265 void SetDefaultAdapterName(); | |
| 266 | |
| 267 // Remove the currently tracked adapter. IsPresent() will return false after | |
| 268 // this is called. | |
| 269 void RemoveAdapter(); | |
| 270 | |
| 271 // Announce to observers a change in the adapter state. | |
| 272 void PoweredChanged(bool powered); | |
| 273 void DiscoverableChanged(bool discoverable); | |
| 274 void DiscoveringChanged(bool discovering); | |
| 275 void PresentChanged(bool present); | |
| 276 | |
| 277 // Called by dbus:: on completion of the discoverable property change. | |
| 278 void OnSetDiscoverable(const base::Closure& callback, | |
| 279 const ErrorCallback& error_callback, | |
| 280 bool success); | |
| 281 | |
| 282 // Called by dbus:: on completion of an adapter property change. | |
| 283 void OnPropertyChangeCompleted(const base::Closure& callback, | |
| 284 const ErrorCallback& error_callback, | |
| 285 bool success); | |
| 286 | |
| 287 // BluetoothAdapter: | |
| 288 void AddDiscoverySession( | |
| 289 device::BluetoothDiscoveryFilter* discovery_filter, | |
| 290 const base::Closure& callback, | |
| 291 const DiscoverySessionErrorCallback& error_callback) override; | |
| 292 void RemoveDiscoverySession( | |
| 293 device::BluetoothDiscoveryFilter* discovery_filter, | |
| 294 const base::Closure& callback, | |
| 295 const DiscoverySessionErrorCallback& error_callback) override; | |
| 296 void SetDiscoveryFilter( | |
| 297 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter, | |
| 298 const base::Closure& callback, | |
| 299 const DiscoverySessionErrorCallback& error_callback) override; | |
| 300 | |
| 301 // Called by dbus:: on completion of the D-Bus method call to start discovery. | |
| 302 void OnStartDiscovery(const base::Closure& callback, | |
| 303 const DiscoverySessionErrorCallback& error_callback); | |
| 304 void OnStartDiscoveryError( | |
| 305 const base::Closure& callback, | |
| 306 const DiscoverySessionErrorCallback& error_callback, | |
| 307 const std::string& error_name, | |
| 308 const std::string& error_message); | |
| 309 | |
| 310 // Called by dbus:: on completion of the D-Bus method call to stop discovery. | |
| 311 void OnStopDiscovery(const base::Closure& callback); | |
| 312 void OnStopDiscoveryError(const DiscoverySessionErrorCallback& error_callback, | |
| 313 const std::string& error_name, | |
| 314 const std::string& error_message); | |
| 315 | |
| 316 void OnPreSetDiscoveryFilter( | |
| 317 const base::Closure& callback, | |
| 318 const DiscoverySessionErrorCallback& error_callback); | |
| 319 void OnPreSetDiscoveryFilterError( | |
| 320 const base::Closure& callback, | |
| 321 const DiscoverySessionErrorCallback& error_callback, | |
| 322 device::UMABluetoothDiscoverySessionOutcome outcome); | |
| 323 void OnSetDiscoveryFilter( | |
| 324 const base::Closure& callback, | |
| 325 const DiscoverySessionErrorCallback& error_callback); | |
| 326 void OnSetDiscoveryFilterError( | |
| 327 const base::Closure& callback, | |
| 328 const DiscoverySessionErrorCallback& error_callback, | |
| 329 const std::string& error_name, | |
| 330 const std::string& error_message); | |
| 331 | |
| 332 // Called by dbus:: on completion of the D-Bus method to register a profile. | |
| 333 void OnRegisterProfile(const device::BluetoothUUID& uuid, | |
| 334 scoped_ptr<BluetoothAdapterProfileChromeOS> profile); | |
| 335 | |
| 336 void SetProfileDelegate( | |
| 337 const device::BluetoothUUID& uuid, | |
| 338 const dbus::ObjectPath& device_path, | |
| 339 bluez::BluetoothProfileServiceProvider::Delegate* delegate, | |
| 340 const ProfileRegisteredCallback& success_callback, | |
| 341 const ErrorCompletionCallback& error_callback); | |
| 342 void OnRegisterProfileError(const device::BluetoothUUID& uuid, | |
| 343 const std::string& error_name, | |
| 344 const std::string& error_message); | |
| 345 | |
| 346 // Called by BluetoothAdapterProfileChromeOS when no users of a profile | |
| 347 // remain. | |
| 348 void RemoveProfile(const device::BluetoothUUID& uuid); | |
| 349 | |
| 350 // Processes the queued discovery requests. For each DiscoveryParamTuple in | |
| 351 // the queue, this method will try to add a new discovery session. This method | |
| 352 // is called whenever a pending D-Bus call to start or stop discovery has | |
| 353 // ended (with either success or failure). | |
| 354 void ProcessQueuedDiscoveryRequests(); | |
| 355 | |
| 356 // Set in |Shutdown()|, makes IsPresent()| return false. | |
| 357 bool dbus_is_shutdown_; | |
| 358 | |
| 359 // Number of discovery sessions that have been added. | |
| 360 int num_discovery_sessions_; | |
| 361 | |
| 362 // True, if there is a pending request to start or stop discovery. | |
| 363 bool discovery_request_pending_; | |
| 364 | |
| 365 // List of queued requests to add new discovery sessions. While there is a | |
| 366 // pending request to BlueZ to start or stop discovery, many requests from | |
| 367 // within Chrome to start or stop discovery sessions may occur. We only | |
| 368 // queue requests to add new sessions to be processed later. All requests to | |
| 369 // remove a session while a call is pending immediately return failure. Note | |
| 370 // that since BlueZ keeps its own reference count of applications that have | |
| 371 // requested discovery, dropping our count to 0 won't necessarily result in | |
| 372 // the controller actually stopping discovery if, for example, an application | |
| 373 // other than Chrome, such as bt_console, was also used to start discovery. | |
| 374 DiscoveryCallbackQueue discovery_request_queue_; | |
| 375 | |
| 376 // Object path of the adapter we track. | |
| 377 dbus::ObjectPath object_path_; | |
| 378 | |
| 379 // Instance of the D-Bus agent object used for pairing, initialized with | |
| 380 // our own class as its delegate. | |
| 381 scoped_ptr<bluez::BluetoothAgentServiceProvider> agent_; | |
| 382 | |
| 383 // UI thread task runner and socket thread object used to create sockets. | |
| 384 scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; | |
| 385 scoped_refptr<device::BluetoothSocketThread> socket_thread_; | |
| 386 | |
| 387 // The profiles we have registered with the bluetooth daemon. | |
| 388 std::map<device::BluetoothUUID, BluetoothAdapterProfileChromeOS*> profiles_; | |
| 389 | |
| 390 // Queue of delegates waiting for a profile to register. | |
| 391 std::map<device::BluetoothUUID, std::vector<RegisterProfileCompletionPair>*> | |
| 392 profile_queues_; | |
| 393 | |
| 394 scoped_ptr<device::BluetoothDiscoveryFilter> current_filter_; | |
| 395 | |
| 396 // Note: This should remain the last member so it'll be destroyed and | |
| 397 // invalidate its weak pointers before any other members are destroyed. | |
| 398 base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_; | |
| 399 | |
| 400 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterChromeOS); | |
| 401 }; | |
| 402 | |
| 403 } // namespace chromeos | |
| 404 | |
| 405 #endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ | |
| OLD | NEW |